~bzr-pqm/bzr/bzr.dev

2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1534.4.39 by Robert Collins
Basic BzrDir support.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1534.4.39 by Robert Collins
Basic BzrDir support.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1534.4.39 by Robert Collins
Basic BzrDir support.
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
"""BzrDir logic. The BzrDir is the basic control directory used by bzr.
18
19
At format 7 this was split out into Branch, Repository and Checkout control
20
directories.
21
"""
22
1773.4.3 by Martin Pool
[merge] bzr.dev
23
# TODO: remove unittest dependency; put that stuff inside the test suite
24
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
25
# TODO: The Format probe_transport seems a bit redundant with just trying to
26
# open the bzrdir. -- mbp
27
#
28
# TODO: Can we move specific formats into separate modules to make this file
29
# smaller?
30
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
31
from cStringIO import StringIO
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
32
import os
2204.4.1 by Aaron Bentley
Add 'formats' help topic
33
import textwrap
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
34
35
from bzrlib.lazy_import import lazy_import
36
lazy_import(globals(), """
37
from copy import deepcopy
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
38
from stat import S_ISDIR
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
39
import unittest
1534.4.39 by Robert Collins
Basic BzrDir support.
40
41
import bzrlib
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
42
from bzrlib import (
43
    errors,
44
    lockable_files,
45
    lockdir,
2204.4.1 by Aaron Bentley
Add 'formats' help topic
46
    registry,
1996.3.12 by John Arbash Meinel
Change how 'revision' is imported to avoid problems later
47
    revision as _mod_revision,
2204.4.12 by Aaron Bentley
Deprecate bzrdir.BzrDirFormat.set_default_format
48
    symbol_versioning,
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
49
    ui,
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
50
    urlutils,
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
51
    xml4,
52
    xml5,
2255.12.1 by Robert Collins
Implement upgrade for working trees.
53
    workingtree,
54
    workingtree_4,
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
55
    )
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
56
from bzrlib.osutils import (
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
57
    safe_unicode,
58
    sha_strings,
59
    sha_string,
60
    )
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
61
from bzrlib.store.revision.text import TextRevisionStore
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
62
from bzrlib.store.text import TextStore
1563.2.25 by Robert Collins
Merge in upstream.
63
from bzrlib.store.versioned import WeaveStore
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
64
from bzrlib.transactions import WriteTransaction
2164.2.21 by Vincent Ladeuil
Take bundles into account.
65
from bzrlib.transport import (
66
    do_catching_redirections,
67
    get_transport,
68
    )
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
69
from bzrlib.weave import Weave
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
70
""")
71
2164.2.1 by v.ladeuil+lp at free
First rough http branch redirection implementation.
72
from bzrlib.trace import (
73
    mutter,
74
    note,
75
    )
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
76
from bzrlib.transport.local import LocalTransport
1534.4.39 by Robert Collins
Basic BzrDir support.
77
78
79
class BzrDir(object):
80
    """A .bzr control diretory.
81
    
82
    BzrDir instances let you create or open any of the things that can be
83
    found within .bzr - checkouts, branches and repositories.
84
    
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
85
    transport
86
        the transport which this bzr dir is rooted at (i.e. file:///.../.bzr/)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
87
    root_transport
88
        a transport connected to the directory this bzr was opened from.
1534.4.39 by Robert Collins
Basic BzrDir support.
89
    """
90
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
91
    def break_lock(self):
92
        """Invoke break_lock on the first object in the bzrdir.
93
94
        If there is a tree, the tree is opened and break_lock() called.
95
        Otherwise, branch is tried, and finally repository.
96
        """
97
        try:
98
            thing_to_unlock = self.open_workingtree()
99
        except (errors.NotLocalUrl, errors.NoWorkingTree):
100
            try:
101
                thing_to_unlock = self.open_branch()
102
            except errors.NotBranchError:
103
                try:
104
                    thing_to_unlock = self.open_repository()
105
                except errors.NoRepositoryPresent:
106
                    return
107
        thing_to_unlock.break_lock()
108
1534.5.16 by Robert Collins
Review feedback.
109
    def can_convert_format(self):
110
        """Return true if this bzrdir is one whose format we can convert from."""
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
111
        return True
112
1910.2.12 by Aaron Bentley
Implement knit repo format 2
113
    def check_conversion_target(self, target_format):
114
        target_repo_format = target_format.repository_format
115
        source_repo_format = self._format.repository_format
116
        source_repo_format.check_conversion_target(target_repo_format)
117
1596.2.1 by Robert Collins
Fix BzrDir.open_containing of unsupported branches.
118
    @staticmethod
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
119
    def _check_supported(format, allow_unsupported,
120
        recommend_upgrade=True,
121
        basedir=None):
122
        """Give an error or warning on old formats.
123
124
        :param format: may be any kind of format - workingtree, branch, 
125
        or repository.
126
127
        :param allow_unsupported: If true, allow opening 
128
        formats that are strongly deprecated, and which may 
129
        have limited functionality.
130
131
        :param recommend_upgrade: If true (default), warn
132
        the user through the ui object that they may wish
133
        to upgrade the object.
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
134
        """
2323.5.19 by Martin Pool
No upgrade recommendation on source when cloning
135
        # TODO: perhaps move this into a base Format class; it's not BzrDir
136
        # specific. mbp 20070323
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
137
        if not allow_unsupported and not format.is_supported():
1596.2.1 by Robert Collins
Fix BzrDir.open_containing of unsupported branches.
138
            # see open_downlevel to open legacy branches.
1740.5.6 by Martin Pool
Clean up many exception classes.
139
            raise errors.UnsupportedFormatError(format=format)
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
140
        if recommend_upgrade \
141
            and getattr(format, 'upgrade_recommended', False):
142
            ui.ui_factory.recommend_upgrade(
143
                format.get_format_description(),
144
                basedir)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
145
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
146
    def clone(self, url, revision_id=None, force_new_repo=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
147
        """Clone this bzrdir and its contents to url verbatim.
148
149
        If urls last component does not exist, it will be created.
150
151
        if revision_id is not None, then the clone operation may tune
152
            itself to download less data.
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
153
        :param force_new_repo: Do not use a shared repository for the target 
154
                               even if one is available.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
155
        """
156
        self._make_tail(url)
157
        result = self._format.initialize(url)
158
        try:
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
159
            local_repo = self.find_repository()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
160
        except errors.NoRepositoryPresent:
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
161
            local_repo = None
162
        if local_repo:
163
            # may need to copy content in
164
            if force_new_repo:
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
165
                result_repo = local_repo.clone(
166
                    result,
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
167
                    revision_id=revision_id)
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
168
                result_repo.set_make_working_trees(local_repo.make_working_trees())
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
169
            else:
170
                try:
171
                    result_repo = result.find_repository()
172
                    # fetch content this dir needs.
173
                    result_repo.fetch(local_repo, revision_id=revision_id)
174
                except errors.NoRepositoryPresent:
175
                    # needed to make one anyway.
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
176
                    result_repo = local_repo.clone(
177
                        result,
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
178
                        revision_id=revision_id)
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
179
                    result_repo.set_make_working_trees(local_repo.make_working_trees())
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
180
        # 1 if there is a branch present
181
        #   make sure its content is available in the target repository
182
        #   clone it.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
183
        try:
184
            self.open_branch().clone(result, revision_id=revision_id)
185
        except errors.NotBranchError:
186
            pass
187
        try:
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
188
            self.open_workingtree().clone(result)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
189
        except (errors.NoWorkingTree, errors.NotLocalUrl):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
190
            pass
191
        return result
192
1685.1.61 by Martin Pool
[broken] Change BzrDir._make_tail to use urlutils.split
193
    # TODO: This should be given a Transport, and should chdir up; otherwise
194
    # this will open a new connection.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
195
    def _make_tail(self, url):
1685.1.61 by Martin Pool
[broken] Change BzrDir._make_tail to use urlutils.split
196
        head, tail = urlutils.split(url)
197
        if tail and tail != '.':
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
198
            t = get_transport(head)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
199
            try:
1685.1.61 by Martin Pool
[broken] Change BzrDir._make_tail to use urlutils.split
200
                t.mkdir(tail)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
201
            except errors.FileExists:
202
                pass
203
1685.1.63 by Martin Pool
Small Transport fixups
204
    # TODO: Should take a Transport
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
205
    @classmethod
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
206
    def create(cls, base, format=None):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
207
        """Create a new BzrDir at the url 'base'.
1534.4.39 by Robert Collins
Basic BzrDir support.
208
        
209
        This will call the current default formats initialize with base
210
        as the only parameter.
211
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
212
        :param format: If supplied, the format of branch to create.  If not
213
            supplied, the default is used.
1534.4.39 by Robert Collins
Basic BzrDir support.
214
        """
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
215
        if cls is not BzrDir:
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
216
            raise AssertionError("BzrDir.create always creates the default"
217
                " format, not one of %r" % cls)
1685.1.62 by Martin Pool
[broken] Change BzrDir.create to use urlutils.split
218
        head, tail = urlutils.split(base)
219
        if tail and tail != '.':
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
220
            t = get_transport(head)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
221
            try:
1685.1.62 by Martin Pool
[broken] Change BzrDir.create to use urlutils.split
222
                t.mkdir(tail)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
223
            except errors.FileExists:
224
                pass
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
225
        if format is None:
226
            format = BzrDirFormat.get_default_format()
227
        return format.initialize(safe_unicode(base))
1534.4.39 by Robert Collins
Basic BzrDir support.
228
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
229
    def create_branch(self):
230
        """Create a branch in this BzrDir.
231
232
        The bzrdirs format will control what branch format is created.
233
        For more control see BranchFormatXX.create(a_bzrdir).
234
        """
235
        raise NotImplementedError(self.create_branch)
236
237
    @staticmethod
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
238
    def create_branch_and_repo(base, force_new_repo=False, format=None):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
239
        """Create a new BzrDir, Branch and Repository at the url 'base'.
240
241
        This will use the current default BzrDirFormat, and use whatever 
242
        repository format that that uses via bzrdir.create_branch and
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
243
        create_repository. If a shared repository is available that is used
244
        preferentially.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
245
246
        The created Branch object is returned.
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
247
248
        :param base: The URL to create the branch at.
249
        :param force_new_repo: If True a new repository is always created.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
250
        """
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
251
        bzrdir = BzrDir.create(base, format)
1534.6.11 by Robert Collins
Review feedback.
252
        bzrdir._find_or_create_repository(force_new_repo)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
253
        return bzrdir.create_branch()
1534.6.11 by Robert Collins
Review feedback.
254
255
    def _find_or_create_repository(self, force_new_repo):
256
        """Create a new repository if needed, returning the repository."""
257
        if force_new_repo:
258
            return self.create_repository()
259
        try:
260
            return self.find_repository()
261
        except errors.NoRepositoryPresent:
262
            return self.create_repository()
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
263
        
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
264
    @staticmethod
1558.5.3 by Aaron Bentley
Init command can produce sharing branches
265
    def create_branch_convenience(base, force_new_repo=False,
266
                                  force_new_tree=None, format=None):
1534.6.10 by Robert Collins
Finish use of repositories support.
267
        """Create a new BzrDir, Branch and Repository at the url 'base'.
268
269
        This is a convenience function - it will use an existing repository
270
        if possible, can be told explicitly whether to create a working tree or
1534.6.12 by Robert Collins
Typo found by John Meinel.
271
        not.
1534.6.10 by Robert Collins
Finish use of repositories support.
272
273
        This will use the current default BzrDirFormat, and use whatever 
274
        repository format that that uses via bzrdir.create_branch and
275
        create_repository. If a shared repository is available that is used
276
        preferentially. Whatever repository is used, its tree creation policy
277
        is followed.
278
279
        The created Branch object is returned.
280
        If a working tree cannot be made due to base not being a file:// url,
1563.1.6 by Robert Collins
Add tests for sftp push, and NonLocalTets for BzrDir.create_branch_convenience, before fixing the failure of it to work on non-local urls.
281
        no error is raised unless force_new_tree is True, in which case no 
282
        data is created on disk and NotLocalUrl is raised.
1534.6.10 by Robert Collins
Finish use of repositories support.
283
284
        :param base: The URL to create the branch at.
285
        :param force_new_repo: If True a new repository is always created.
286
        :param force_new_tree: If True or False force creation of a tree or 
287
                               prevent such creation respectively.
1558.5.3 by Aaron Bentley
Init command can produce sharing branches
288
        :param format: Override for the for the bzrdir format to create
1534.6.10 by Robert Collins
Finish use of repositories support.
289
        """
1563.1.6 by Robert Collins
Add tests for sftp push, and NonLocalTets for BzrDir.create_branch_convenience, before fixing the failure of it to work on non-local urls.
290
        if force_new_tree:
291
            # check for non local urls
292
            t = get_transport(safe_unicode(base))
293
            if not isinstance(t, LocalTransport):
294
                raise errors.NotLocalUrl(base)
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
295
        bzrdir = BzrDir.create(base, format)
1534.6.11 by Robert Collins
Review feedback.
296
        repo = bzrdir._find_or_create_repository(force_new_repo)
1534.6.10 by Robert Collins
Finish use of repositories support.
297
        result = bzrdir.create_branch()
298
        if force_new_tree or (repo.make_working_trees() and 
299
                              force_new_tree is None):
1563.1.6 by Robert Collins
Add tests for sftp push, and NonLocalTets for BzrDir.create_branch_convenience, before fixing the failure of it to work on non-local urls.
300
            try:
301
                bzrdir.create_workingtree()
302
            except errors.NotLocalUrl:
303
                pass
1534.6.10 by Robert Collins
Finish use of repositories support.
304
        return result
1551.8.4 by Aaron Bentley
Tweak import style
305
        
1551.8.2 by Aaron Bentley
Add create_checkout_convenience
306
    @staticmethod
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
307
    def create_repository(base, shared=False, format=None):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
308
        """Create a new BzrDir and Repository at the url 'base'.
309
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
310
        If no format is supplied, this will default to the current default
311
        BzrDirFormat by default, and use whatever repository format that that
312
        uses for bzrdirformat.create_repository.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
313
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
314
        :param shared: Create a shared repository rather than a standalone
1534.6.1 by Robert Collins
allow API creation of shared repositories
315
                       repository.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
316
        The Repository object is returned.
317
318
        This must be overridden as an instance method in child classes, where
319
        it should take no parameters and construct whatever repository format
320
        that child class desires.
321
        """
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
322
        bzrdir = BzrDir.create(base, format)
1841.2.1 by Jelmer Vernooij
Fix handling of `shared' parameter in BzrDir.create_repository().
323
        return bzrdir.create_repository(shared)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
324
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
325
    @staticmethod
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
326
    def create_standalone_workingtree(base, format=None):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
327
        """Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
328
329
        'base' must be a local path or a file:// url.
330
331
        This will use the current default BzrDirFormat, and use whatever 
332
        repository format that that uses for bzrdirformat.create_workingtree,
333
        create_branch and create_repository.
334
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
335
        :return: The WorkingTree object.
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
336
        """
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
337
        t = get_transport(safe_unicode(base))
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
338
        if not isinstance(t, LocalTransport):
339
            raise errors.NotLocalUrl(base)
1534.6.10 by Robert Collins
Finish use of repositories support.
340
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
341
                                               force_new_repo=True,
342
                                               format=format).bzrdir
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
343
        return bzrdir.create_workingtree()
344
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
345
    def create_workingtree(self, revision_id=None):
346
        """Create a working tree at this BzrDir.
347
        
348
        revision_id: create it as of this revision id.
349
        """
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
350
        raise NotImplementedError(self.create_workingtree)
351
2255.14.1 by Martin Pool
Add BzrDir.retire_bzrdir and partly fix subsume
352
    def retire_bzrdir(self):
353
        """Permanently disable the bzrdir.
354
355
        This is done by renaming it to give the user some ability to recover
356
        if there was a problem.
357
358
        This will have horrible consequences if anyone has anything locked or
359
        in use.
360
        """
361
        for i in xrange(10000):
362
            try:
363
                to_path = '.bzr.retired.%d' % i
364
                self.root_transport.rename('.bzr', to_path)
365
                note("renamed %s to %s"
366
                    % (self.root_transport.abspath('.bzr'), to_path))
367
                break
368
            except (errors.TransportError, IOError, errors.PathError):
369
                pass
370
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
371
    def destroy_workingtree(self):
1551.8.36 by Aaron Bentley
Introduce BzrDir.destroy_workingtree
372
        """Destroy the working tree at this BzrDir.
373
374
        Formats that do not support this may raise UnsupportedOperation.
375
        """
376
        raise NotImplementedError(self.destroy_workingtree)
377
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
378
    def destroy_workingtree_metadata(self):
379
        """Destroy the control files for the working tree at this BzrDir.
380
381
        The contents of working tree files are not affected.
382
        Formats that do not support this may raise UnsupportedOperation.
383
        """
384
        raise NotImplementedError(self.destroy_workingtree_metadata)
385
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
386
    def find_repository(self):
387
        """Find the repository that should be used for a_bzrdir.
388
389
        This does not require a branch as we use it to find the repo for
390
        new branches as well as to hook existing branches up to their
391
        repository.
392
        """
393
        try:
394
            return self.open_repository()
395
        except errors.NoRepositoryPresent:
396
            pass
397
        next_transport = self.root_transport.clone('..')
398
        while True:
1725.2.5 by Robert Collins
Bugfix create_branch_convenience at the root of a file system to not loop
399
            # find the next containing bzrdir
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
400
            try:
1534.6.11 by Robert Collins
Review feedback.
401
                found_bzrdir = BzrDir.open_containing_from_transport(
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
402
                    next_transport)[0]
403
            except errors.NotBranchError:
1725.2.5 by Robert Collins
Bugfix create_branch_convenience at the root of a file system to not loop
404
                # none found
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
405
                raise errors.NoRepositoryPresent(self)
1725.2.5 by Robert Collins
Bugfix create_branch_convenience at the root of a file system to not loop
406
            # does it have a repository ?
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
407
            try:
408
                repository = found_bzrdir.open_repository()
409
            except errors.NoRepositoryPresent:
410
                next_transport = found_bzrdir.root_transport.clone('..')
1725.2.5 by Robert Collins
Bugfix create_branch_convenience at the root of a file system to not loop
411
                if (found_bzrdir.root_transport.base == next_transport.base):
412
                    # top of the file system
413
                    break
414
                else:
415
                    continue
1534.6.6 by Robert Collins
Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.
416
            if ((found_bzrdir.root_transport.base == 
417
                 self.root_transport.base) or repository.is_shared()):
418
                return repository
419
            else:
420
                raise errors.NoRepositoryPresent(self)
421
        raise errors.NoRepositoryPresent(self)
422
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
423
    def get_branch_transport(self, branch_format):
424
        """Get the transport for use by branch format in this BzrDir.
425
426
        Note that bzr dirs that do not support format strings will raise
427
        IncompatibleFormat if the branch format they are given has
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
428
        a format string, and vice versa.
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
429
430
        If branch_format is None, the transport is returned with no 
431
        checking. if it is not None, then the returned transport is
432
        guaranteed to point to an existing directory ready for use.
433
        """
434
        raise NotImplementedError(self.get_branch_transport)
435
        
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
436
    def get_repository_transport(self, repository_format):
437
        """Get the transport for use by repository format in this BzrDir.
438
439
        Note that bzr dirs that do not support format strings will raise
440
        IncompatibleFormat if the repository format they are given has
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
441
        a format string, and vice versa.
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
442
443
        If repository_format is None, the transport is returned with no 
444
        checking. if it is not None, then the returned transport is
445
        guaranteed to point to an existing directory ready for use.
446
        """
447
        raise NotImplementedError(self.get_repository_transport)
448
        
1534.4.53 by Robert Collins
Review feedback from John Meinel.
449
    def get_workingtree_transport(self, tree_format):
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
450
        """Get the transport for use by workingtree format in this BzrDir.
451
452
        Note that bzr dirs that do not support format strings will raise
2100.3.11 by Aaron Bentley
Add join --reference support
453
        IncompatibleFormat if the workingtree format they are given has a
454
        format string, and vice versa.
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
455
456
        If workingtree_format is None, the transport is returned with no 
457
        checking. if it is not None, then the returned transport is
458
        guaranteed to point to an existing directory ready for use.
459
        """
460
        raise NotImplementedError(self.get_workingtree_transport)
461
        
1534.4.39 by Robert Collins
Basic BzrDir support.
462
    def __init__(self, _transport, _format):
463
        """Initialize a Bzr control dir object.
464
        
465
        Only really common logic should reside here, concrete classes should be
466
        made with varying behaviours.
467
1534.4.53 by Robert Collins
Review feedback from John Meinel.
468
        :param _format: the format that is creating this BzrDir instance.
469
        :param _transport: the transport this dir is based at.
1534.4.39 by Robert Collins
Basic BzrDir support.
470
        """
471
        self._format = _format
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
472
        self.transport = _transport.clone('.bzr')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
473
        self.root_transport = _transport
1534.4.39 by Robert Collins
Basic BzrDir support.
474
1713.1.9 by Robert Collins
Paired performance tuning of bzr add. (Robert Collins, Martin Pool).
475
    def is_control_filename(self, filename):
476
        """True if filename is the name of a path which is reserved for bzrdir's.
477
        
478
        :param filename: A filename within the root transport of this bzrdir.
479
480
        This is true IF and ONLY IF the filename is part of the namespace reserved
481
        for bzr control dirs. Currently this is the '.bzr' directory in the root
482
        of the root_transport. it is expected that plugins will need to extend
483
        this in the future - for instance to make bzr talk with svn working
484
        trees.
485
        """
486
        # this might be better on the BzrDirFormat class because it refers to 
487
        # all the possible bzrdir disk formats. 
488
        # This method is tested via the workingtree is_control_filename tests- 
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
489
        # it was extracted from WorkingTree.is_control_filename. If the methods
1713.1.9 by Robert Collins
Paired performance tuning of bzr add. (Robert Collins, Martin Pool).
490
        # contract is extended beyond the current trivial  implementation please
491
        # add new tests for it to the appropriate place.
492
        return filename == '.bzr' or filename.startswith('.bzr/')
493
1534.5.16 by Robert Collins
Review feedback.
494
    def needs_format_conversion(self, format=None):
495
        """Return true if this bzrdir needs convert_format run on it.
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
496
        
497
        For instance, if the repository format is out of date but the 
498
        branch and working tree are not, this should return True.
1534.5.13 by Robert Collins
Correct buggy test.
499
500
        :param format: Optional parameter indicating a specific desired
1534.5.16 by Robert Collins
Review feedback.
501
                       format we plan to arrive at.
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
502
        """
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
503
        raise NotImplementedError(self.needs_format_conversion)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
504
1534.4.39 by Robert Collins
Basic BzrDir support.
505
    @staticmethod
506
    def open_unsupported(base):
507
        """Open a branch which is not supported."""
508
        return BzrDir.open(base, _unsupported=True)
509
        
510
    @staticmethod
511
    def open(base, _unsupported=False):
1534.4.53 by Robert Collins
Review feedback from John Meinel.
512
        """Open an existing bzrdir, rooted at 'base' (url)
1534.4.39 by Robert Collins
Basic BzrDir support.
513
        
514
        _unsupported is a private parameter to the BzrDir class.
515
        """
516
        t = get_transport(base)
1910.11.1 by Andrew Bennetts
Add BzrDir.open_from_transport, refactored from duplicate code, no explicit tests.
517
        return BzrDir.open_from_transport(t, _unsupported=_unsupported)
518
519
    @staticmethod
520
    def open_from_transport(transport, _unsupported=False):
521
        """Open a bzrdir within a particular directory.
522
523
        :param transport: Transport containing the bzrdir.
524
        :param _unsupported: private.
525
        """
2164.2.21 by Vincent Ladeuil
Take bundles into account.
526
        base = transport.base
527
528
        def find_format(transport):
529
            return transport, BzrDirFormat.find_format(transport)
530
531
        def redirected(transport, e, redirection_notice):
532
            qualified_source = e.get_source_url()
533
            relpath = transport.relpath(qualified_source)
534
            if not e.target.endswith(relpath):
535
                # Not redirected to a branch-format, not a branch
536
                raise errors.NotBranchError(path=e.target)
537
            target = e.target[:-len(relpath)]
538
            note('%s is%s redirected to %s',
539
                 transport.base, e.permanently, target)
540
            # Let's try with a new transport
541
            qualified_target = e.get_target_url()[:-len(relpath)]
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
542
            # FIXME: If 'transport' has a qualifier, this should
2164.2.21 by Vincent Ladeuil
Take bundles into account.
543
            # be applied again to the new transport *iff* the
544
            # schemes used are the same. It's a bit tricky to
545
            # verify, so I'll punt for now
546
            # -- vila20070212
547
            return get_transport(target)
548
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
549
        try:
2164.2.28 by Vincent Ladeuil
TestingHTTPServer.test_case_server renamed from test_case to avoid confusions.
550
            transport, format = do_catching_redirections(find_format,
551
                                                         transport,
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
552
                                                         redirected)
553
        except errors.TooManyRedirections:
554
            raise errors.NotBranchError(base)
2164.2.21 by Vincent Ladeuil
Take bundles into account.
555
1596.2.1 by Robert Collins
Fix BzrDir.open_containing of unsupported branches.
556
        BzrDir._check_supported(format, _unsupported)
1910.11.1 by Andrew Bennetts
Add BzrDir.open_from_transport, refactored from duplicate code, no explicit tests.
557
        return format.open(transport, _found=True)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
558
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
559
    def open_branch(self, unsupported=False):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
560
        """Open the branch object at this BzrDir if one is present.
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
561
562
        If unsupported is True, then no longer supported branch formats can
563
        still be opened.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
564
        
565
        TODO: static convenience version of this?
566
        """
567
        raise NotImplementedError(self.open_branch)
1534.4.39 by Robert Collins
Basic BzrDir support.
568
569
    @staticmethod
570
    def open_containing(url):
571
        """Open an existing branch which contains url.
572
        
1534.6.3 by Robert Collins
find_repository sufficiently robust.
573
        :param url: url to search from.
1534.6.11 by Robert Collins
Review feedback.
574
        See open_containing_from_transport for more detail.
1534.6.3 by Robert Collins
find_repository sufficiently robust.
575
        """
1534.6.11 by Robert Collins
Review feedback.
576
        return BzrDir.open_containing_from_transport(get_transport(url))
1534.6.3 by Robert Collins
find_repository sufficiently robust.
577
    
578
    @staticmethod
1534.6.11 by Robert Collins
Review feedback.
579
    def open_containing_from_transport(a_transport):
1534.6.3 by Robert Collins
find_repository sufficiently robust.
580
        """Open an existing branch which contains a_transport.base
581
582
        This probes for a branch at a_transport, and searches upwards from there.
1534.4.39 by Robert Collins
Basic BzrDir support.
583
584
        Basically we keep looking up until we find the control directory or
585
        run into the root.  If there isn't one, raises NotBranchError.
586
        If there is one and it is either an unrecognised format or an unsupported 
587
        format, UnknownFormatError or UnsupportedFormatError are raised.
588
        If there is one, it is returned, along with the unused portion of url.
1685.1.27 by John Arbash Meinel
BzrDir works in URLs, but WorkingTree works in unicode paths
589
1685.1.28 by John Arbash Meinel
Changing open_containing to always return a unicode path.
590
        :return: The BzrDir that contains the path, and a Unicode path 
591
                for the rest of the URL.
1534.4.39 by Robert Collins
Basic BzrDir support.
592
        """
593
        # this gets the normalised url back. I.e. '.' -> the full path.
1534.6.3 by Robert Collins
find_repository sufficiently robust.
594
        url = a_transport.base
1534.4.39 by Robert Collins
Basic BzrDir support.
595
        while True:
596
            try:
1910.11.1 by Andrew Bennetts
Add BzrDir.open_from_transport, refactored from duplicate code, no explicit tests.
597
                result = BzrDir.open_from_transport(a_transport)
598
                return result, urlutils.unescape(a_transport.relpath(url))
1534.4.39 by Robert Collins
Basic BzrDir support.
599
            except errors.NotBranchError, e:
1685.1.60 by Martin Pool
[broken] NotBranchError should unescape the url if possible
600
                pass
1534.6.3 by Robert Collins
find_repository sufficiently robust.
601
            new_t = a_transport.clone('..')
602
            if new_t.base == a_transport.base:
1534.4.39 by Robert Collins
Basic BzrDir support.
603
                # reached the root, whatever that may be
604
                raise errors.NotBranchError(path=url)
1534.6.3 by Robert Collins
find_repository sufficiently robust.
605
            a_transport = new_t
1534.4.39 by Robert Collins
Basic BzrDir support.
606
2215.3.2 by Aaron Bentley
Add open_containing_tree_or_branch
607
    @classmethod
608
    def open_containing_tree_or_branch(klass, location):
609
        """Return the branch and working tree contained by a location.
610
611
        Returns (tree, branch, relpath).
612
        If there is no tree at containing the location, tree will be None.
613
        If there is no branch containing the location, an exception will be
614
        raised
615
        relpath is the portion of the path that is contained by the branch.
616
        """
617
        bzrdir, relpath = klass.open_containing(location)
618
        try:
619
            tree = bzrdir.open_workingtree()
2215.3.5 by Aaron Bentley
Add support for remote ls
620
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2215.3.2 by Aaron Bentley
Add open_containing_tree_or_branch
621
            tree = None
622
            branch = bzrdir.open_branch()
623
        else:
624
            branch = tree.branch
625
        return tree, branch, relpath
626
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
627
    def open_repository(self, _unsupported=False):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
628
        """Open the repository object at this BzrDir if one is present.
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
629
630
        This will not follow the Branch object pointer - its strictly a direct
631
        open facility. Most client code should use open_branch().repository to
632
        get at a repository.
633
634
        _unsupported is a private parameter, not part of the api.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
635
        TODO: static convenience version of this?
636
        """
637
        raise NotImplementedError(self.open_repository)
638
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
639
    def open_workingtree(self, _unsupported=False):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
640
        """Open the workingtree object at this BzrDir if one is present.
641
        
642
        TODO: static convenience version of this?
643
        """
644
        raise NotImplementedError(self.open_workingtree)
645
1662.1.19 by Martin Pool
Better error message when initting existing tree
646
    def has_branch(self):
647
        """Tell if this bzrdir contains a branch.
648
        
649
        Note: if you're going to open the branch, you should just go ahead
650
        and try, and not ask permission first.  (This method just opens the 
651
        branch and discards it, and that's somewhat expensive.) 
652
        """
653
        try:
654
            self.open_branch()
655
            return True
656
        except errors.NotBranchError:
657
            return False
658
659
    def has_workingtree(self):
660
        """Tell if this bzrdir contains a working tree.
661
662
        This will still raise an exception if the bzrdir has a workingtree that
663
        is remote & inaccessible.
664
        
665
        Note: if you're going to open the working tree, you should just go ahead
666
        and try, and not ask permission first.  (This method just opens the 
667
        workingtree and discards it, and that's somewhat expensive.) 
668
        """
669
        try:
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
670
            self.open_workingtree(recommend_upgrade=False)
1662.1.19 by Martin Pool
Better error message when initting existing tree
671
            return True
672
        except errors.NoWorkingTree:
673
            return False
674
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
675
    def _cloning_metadir(self):
676
        result_format = self._format.__class__()
677
        try:
1910.2.41 by Aaron Bentley
Clean up clone format creation
678
            try:
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
679
                branch = self.open_branch()
680
                source_repository = branch.repository
1910.2.41 by Aaron Bentley
Clean up clone format creation
681
            except errors.NotBranchError:
682
                source_branch = None
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
683
                source_repository = self.open_repository()
1910.2.41 by Aaron Bentley
Clean up clone format creation
684
            result_format.repository_format = source_repository._format
685
        except errors.NoRepositoryPresent:
2100.3.24 by Aaron Bentley
Get all tests passing again
686
            source_repository = None
2100.3.28 by Aaron Bentley
Make sprout recursive
687
        try:
2323.5.19 by Martin Pool
No upgrade recommendation on source when cloning
688
            # TODO: Couldn't we just probe for the format in these cases,
689
            # rather than opening the whole tree?  It would be a little
690
            # faster. mbp 20070401
691
            tree = self.open_workingtree(recommend_upgrade=False)
2100.3.28 by Aaron Bentley
Make sprout recursive
692
        except (errors.NoWorkingTree, errors.NotLocalUrl):
693
            result_format.workingtree_format = None
694
        else:
695
            result_format.workingtree_format = tree._format.__class__()
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
696
        return result_format, source_repository
697
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
698
    def cloning_metadir(self):
2100.3.32 by Aaron Bentley
fix tree format, basis_tree call, in sprout
699
        """Produce a metadir suitable for cloning or sprouting with.
1910.2.41 by Aaron Bentley
Clean up clone format creation
700
2100.3.32 by Aaron Bentley
fix tree format, basis_tree call, in sprout
701
        These operations may produce workingtrees (yes, even though they're
702
        "cloning" something that doesn't have a tree, so a viable workingtree
703
        format must be selected.
704
        """
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
705
        format, repository = self._cloning_metadir()
2100.3.32 by Aaron Bentley
fix tree format, basis_tree call, in sprout
706
        if format._workingtree_format is None:
2100.3.34 by Aaron Bentley
Fix BzrDir.cloning_metadir with no format
707
            if repository is None:
708
                return format
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
709
            tree_format = repository._format._matchingbzrdir.workingtree_format
2100.3.28 by Aaron Bentley
Make sprout recursive
710
            format.workingtree_format = tree_format.__class__()
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
711
        return format
712
2100.3.32 by Aaron Bentley
fix tree format, basis_tree call, in sprout
713
    def checkout_metadir(self):
714
        return self.cloning_metadir()
715
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
716
    def sprout(self, url, revision_id=None, force_new_repo=False,
2100.3.28 by Aaron Bentley
Make sprout recursive
717
               recurse='down'):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
718
        """Create a copy of this bzrdir prepared for use as a new line of
719
        development.
720
721
        If urls last component does not exist, it will be created.
722
723
        Attributes related to the identity of the source branch like
724
        branch nickname will be cleaned, a working tree is created
725
        whether one existed before or not; and a local branch is always
726
        created.
727
728
        if revision_id is not None, then the clone operation may tune
729
            itself to download less data.
730
        """
731
        self._make_tail(url)
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
732
        cloning_format = self.cloning_metadir()
1910.2.41 by Aaron Bentley
Clean up clone format creation
733
        result = cloning_format.initialize(url)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
734
        try:
735
            source_branch = self.open_branch()
736
            source_repository = source_branch.repository
737
        except errors.NotBranchError:
738
            source_branch = None
739
            try:
740
                source_repository = self.open_repository()
741
            except errors.NoRepositoryPresent:
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
742
                source_repository = None
1534.6.9 by Robert Collins
sprouting into shared repositories
743
        if force_new_repo:
744
            result_repo = None
745
        else:
746
            try:
747
                result_repo = result.find_repository()
748
            except errors.NoRepositoryPresent:
749
                result_repo = None
750
        if source_repository is None and result_repo is not None:
751
            pass
752
        elif source_repository is None and result_repo is None:
753
            # no repo available, make a new one
754
            result.create_repository()
755
        elif source_repository is not None and result_repo is None:
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
756
            # have source, and want to make a new target repo
1759.2.2 by Jelmer Vernooij
Revert some of my spelling fixes and fix some typos after review by Aaron.
757
            # we don't clone the repo because that preserves attributes
1707.1.1 by Robert Collins
Bugfixes to bzrdir.sprout and clone. Sprout was failing to reset the
758
            # like is_shared(), and we have not yet implemented a 
759
            # repository sprout().
760
            result_repo = result.create_repository()
761
        if result_repo is not None:
1534.6.9 by Robert Collins
sprouting into shared repositories
762
            # fetch needed content into target.
1910.4.10 by Andrew Bennetts
Skip various test_sprout* tests when sprouting to non-local bzrdirs that can't have working trees; plus fix a test method naming clash and the bug it revealed in bzrdir.sprout.
763
            if source_repository is not None:
764
                result_repo.fetch(source_repository, revision_id=revision_id)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
765
        if source_branch is not None:
766
            source_branch.sprout(result, revision_id=revision_id)
767
        else:
768
            result.create_branch()
1685.1.20 by John Arbash Meinel
More changes to get 'bzr branch' and 'bzr pull' to work
769
        # TODO: jam 20060426 we probably need a test in here in the
770
        #       case that the newly sprouted branch is a remote one
1558.5.8 by Aaron Bentley
Bugfix when result_repo is None
771
        if result_repo is None or result_repo.make_working_trees():
1731.1.33 by Aaron Bentley
Revert no-special-root changes
772
            wt = result.create_workingtree()
2255.2.77 by Robert Collins
Tune working inventory generation more: walk the blocks, skipping deleted rows.
773
            wt.lock_write()
774
            try:
775
                if wt.path2id('') is None:
776
                    try:
777
                        wt.set_root_id(self.open_workingtree.get_root_id())
778
                    except errors.NoWorkingTree:
779
                        pass
780
            finally:
781
                wt.unlock()
2100.3.28 by Aaron Bentley
Make sprout recursive
782
        else:
783
            wt = None
784
        if recurse == 'down':
785
            if wt is not None:
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
786
                basis = wt.basis_tree()
787
                basis.lock_read()
788
                subtrees = basis.iter_references()
2100.3.28 by Aaron Bentley
Make sprout recursive
789
                recurse_branch = wt.branch
790
            elif source_branch is not None:
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
791
                basis = source_branch.basis_tree()
792
                basis.lock_read()
793
                subtrees = basis.iter_references()
2100.3.28 by Aaron Bentley
Make sprout recursive
794
                recurse_branch = source_branch
795
            else:
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
796
                subtrees = []
797
                basis = None
798
            try:
799
                for path, file_id in subtrees:
800
                    target = urlutils.join(url, urlutils.escape(path))
801
                    sublocation = source_branch.reference_parent(file_id, path)
802
                    sublocation.bzrdir.sprout(target,
803
                        basis.get_reference_revision(file_id, path),
804
                        force_new_repo=force_new_repo, recurse=recurse)
805
            finally:
806
                if basis is not None:
807
                    basis.unlock()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
808
        return result
809
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
810
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
811
class BzrDirPreSplitOut(BzrDir):
812
    """A common class for the all-in-one formats."""
813
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
814
    def __init__(self, _transport, _format):
815
        """See BzrDir.__init__."""
816
        super(BzrDirPreSplitOut, self).__init__(_transport, _format)
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
817
        assert self._format._lock_class == lockable_files.TransportLock
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
818
        assert self._format._lock_file_name == 'branch-lock'
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
819
        self._control_files = lockable_files.LockableFiles(
820
                                            self.get_branch_transport(None),
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
821
                                            self._format._lock_file_name,
822
                                            self._format._lock_class)
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
823
1687.1.12 by Robert Collins
Hook in the full break-lock ui.
824
    def break_lock(self):
825
        """Pre-splitout bzrdirs do not suffer from stale locks."""
826
        raise NotImplementedError(self.break_lock)
827
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
828
    def clone(self, url, revision_id=None, force_new_repo=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
829
        """See BzrDir.clone()."""
830
        from bzrlib.workingtree import WorkingTreeFormat2
831
        self._make_tail(url)
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
832
        result = self._format._initialize_for_clone(url)
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
833
        self.open_repository().clone(result, revision_id=revision_id)
1692.7.9 by Martin Pool
Don't create broken standalone branches over sftp (Malone #43064)
834
        from_branch = self.open_branch()
835
        from_branch.clone(result, revision_id=revision_id)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
836
        try:
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
837
            self.open_workingtree().clone(result)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
838
        except errors.NotLocalUrl:
839
            # make a new one, this format always has to have one.
1563.2.38 by Robert Collins
make push preserve tree formats.
840
            try:
841
                WorkingTreeFormat2().initialize(result)
842
            except errors.NotLocalUrl:
1692.7.9 by Martin Pool
Don't create broken standalone branches over sftp (Malone #43064)
843
                # but we cannot do it for remote trees.
844
                to_branch = result.open_branch()
845
                WorkingTreeFormat2().stub_initialize_remote(to_branch.control_files)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
846
        return result
847
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
848
    def create_branch(self):
849
        """See BzrDir.create_branch."""
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
850
        return self.open_branch()
851
1534.6.1 by Robert Collins
allow API creation of shared repositories
852
    def create_repository(self, shared=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
853
        """See BzrDir.create_repository."""
1534.6.1 by Robert Collins
allow API creation of shared repositories
854
        if shared:
855
            raise errors.IncompatibleFormat('shared repository', self._format)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
856
        return self.open_repository()
857
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
858
    def create_workingtree(self, revision_id=None):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
859
        """See BzrDir.create_workingtree."""
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
860
        # this looks buggy but is not -really-
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
861
        # because this format creates the workingtree when the bzrdir is
862
        # created
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
863
        # clone and sprout will have set the revision_id
864
        # and that will have set it for us, its only
865
        # specific uses of create_workingtree in isolation
866
        # that can do wonky stuff here, and that only
867
        # happens for creating checkouts, which cannot be 
868
        # done on this format anyway. So - acceptable wart.
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
869
        result = self.open_workingtree(recommend_upgrade=False)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
870
        if revision_id is not None:
1996.3.12 by John Arbash Meinel
Change how 'revision' is imported to avoid problems later
871
            if revision_id == _mod_revision.NULL_REVISION:
1551.8.20 by Aaron Bentley
Fix BzrDir.create_workingtree for NULL_REVISION
872
                result.set_parent_ids([])
873
            else:
874
                result.set_parent_ids([revision_id])
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
875
        return result
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
876
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
877
    def destroy_workingtree(self):
1551.8.36 by Aaron Bentley
Introduce BzrDir.destroy_workingtree
878
        """See BzrDir.destroy_workingtree."""
879
        raise errors.UnsupportedOperation(self.destroy_workingtree, self)
880
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
881
    def destroy_workingtree_metadata(self):
882
        """See BzrDir.destroy_workingtree_metadata."""
883
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata, 
884
                                          self)
885
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
886
    def get_branch_transport(self, branch_format):
887
        """See BzrDir.get_branch_transport()."""
888
        if branch_format is None:
889
            return self.transport
890
        try:
891
            branch_format.get_format_string()
892
        except NotImplementedError:
893
            return self.transport
894
        raise errors.IncompatibleFormat(branch_format, self._format)
895
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
896
    def get_repository_transport(self, repository_format):
897
        """See BzrDir.get_repository_transport()."""
898
        if repository_format is None:
899
            return self.transport
900
        try:
901
            repository_format.get_format_string()
902
        except NotImplementedError:
903
            return self.transport
904
        raise errors.IncompatibleFormat(repository_format, self._format)
905
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
906
    def get_workingtree_transport(self, workingtree_format):
907
        """See BzrDir.get_workingtree_transport()."""
908
        if workingtree_format is None:
909
            return self.transport
910
        try:
911
            workingtree_format.get_format_string()
912
        except NotImplementedError:
913
            return self.transport
914
        raise errors.IncompatibleFormat(workingtree_format, self._format)
915
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
916
    def needs_format_conversion(self, format=None):
917
        """See BzrDir.needs_format_conversion()."""
918
        # if the format is not the same as the system default,
919
        # an upgrade is needed.
920
        if format is None:
921
            format = BzrDirFormat.get_default_format()
922
        return not isinstance(self._format, format.__class__)
923
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
924
    def open_branch(self, unsupported=False):
925
        """See BzrDir.open_branch."""
926
        from bzrlib.branch import BzrBranchFormat4
927
        format = BzrBranchFormat4()
928
        self._check_supported(format, unsupported)
929
        return format.open(self, _found=True)
930
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
931
    def sprout(self, url, revision_id=None, force_new_repo=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
932
        """See BzrDir.sprout()."""
933
        from bzrlib.workingtree import WorkingTreeFormat2
934
        self._make_tail(url)
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
935
        result = self._format._initialize_for_clone(url)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
936
        try:
2387.1.1 by Robert Collins
Remove the --basis parameter to clone etc. (Robert Collins)
937
            self.open_repository().clone(result, revision_id=revision_id)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
938
        except errors.NoRepositoryPresent:
939
            pass
940
        try:
941
            self.open_branch().sprout(result, revision_id=revision_id)
942
        except errors.NotBranchError:
943
            pass
1587.1.5 by Robert Collins
Put bzr branch behaviour back to the 0.7 ignore-working-tree state.
944
        # we always want a working tree
945
        WorkingTreeFormat2().initialize(result)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
946
        return result
947
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
948
949
class BzrDir4(BzrDirPreSplitOut):
1508.1.25 by Robert Collins
Update per review comments.
950
    """A .bzr version 4 control object.
951
    
952
    This is a deprecated format and may be removed after sept 2006.
953
    """
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
954
1534.6.1 by Robert Collins
allow API creation of shared repositories
955
    def create_repository(self, shared=False):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
956
        """See BzrDir.create_repository."""
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
957
        return self._format.repository_format.initialize(self, shared)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
958
1534.5.16 by Robert Collins
Review feedback.
959
    def needs_format_conversion(self, format=None):
960
        """Format 4 dirs are always in need of conversion."""
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
961
        return True
962
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
963
    def open_repository(self):
964
        """See BzrDir.open_repository."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
965
        from bzrlib.repofmt.weaverepo import RepositoryFormat4
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
966
        return RepositoryFormat4().open(self, _found=True)
967
968
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
969
class BzrDir5(BzrDirPreSplitOut):
1508.1.25 by Robert Collins
Update per review comments.
970
    """A .bzr version 5 control object.
971
972
    This is a deprecated format and may be removed after sept 2006.
973
    """
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
974
975
    def open_repository(self):
976
        """See BzrDir.open_repository."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
977
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
978
        return RepositoryFormat5().open(self, _found=True)
979
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
980
    def open_workingtree(self, _unsupported=False,
981
            recommend_upgrade=True):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
982
        """See BzrDir.create_workingtree."""
983
        from bzrlib.workingtree import WorkingTreeFormat2
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
984
        wt_format = WorkingTreeFormat2()
985
        # we don't warn here about upgrades; that ought to be handled for the
986
        # bzrdir as a whole
987
        return wt_format.open(self, _found=True)
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
988
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
989
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
990
class BzrDir6(BzrDirPreSplitOut):
1508.1.25 by Robert Collins
Update per review comments.
991
    """A .bzr version 6 control object.
992
993
    This is a deprecated format and may be removed after sept 2006.
994
    """
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
995
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
996
    def open_repository(self):
997
        """See BzrDir.open_repository."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
998
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
999
        return RepositoryFormat6().open(self, _found=True)
1000
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1001
    def open_workingtree(self, _unsupported=False,
1002
        recommend_upgrade=True):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1003
        """See BzrDir.create_workingtree."""
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1004
        # we don't warn here about upgrades; that ought to be handled for the
1005
        # bzrdir as a whole
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1006
        from bzrlib.workingtree import WorkingTreeFormat2
1007
        return WorkingTreeFormat2().open(self, _found=True)
1008
1009
1010
class BzrDirMeta1(BzrDir):
1011
    """A .bzr meta version 1 control object.
1012
    
1013
    This is the first control object where the 
1553.5.67 by Martin Pool
doc
1014
    individual aspects are really split out: there are separate repository,
1015
    workingtree and branch subdirectories and any subset of the three can be
1016
    present within a BzrDir.
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1017
    """
1018
1534.5.16 by Robert Collins
Review feedback.
1019
    def can_convert_format(self):
1020
        """See BzrDir.can_convert_format()."""
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1021
        return True
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1022
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1023
    def create_branch(self):
1024
        """See BzrDir.create_branch."""
2230.3.55 by Aaron Bentley
Updates from review
1025
        return self._format.get_branch_format().initialize(self)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1026
1534.6.1 by Robert Collins
allow API creation of shared repositories
1027
    def create_repository(self, shared=False):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1028
        """See BzrDir.create_repository."""
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1029
        return self._format.repository_format.initialize(self, shared)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1030
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1031
    def create_workingtree(self, revision_id=None):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1032
        """See BzrDir.create_workingtree."""
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1033
        from bzrlib.workingtree import WorkingTreeFormat
2100.3.10 by Aaron Bentley
Ensure added references are serialized properly, beef up Workingtreee3
1034
        return self._format.workingtree_format.initialize(self, revision_id)
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1035
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
1036
    def destroy_workingtree(self):
1551.8.36 by Aaron Bentley
Introduce BzrDir.destroy_workingtree
1037
        """See BzrDir.destroy_workingtree."""
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1038
        wt = self.open_workingtree(recommend_upgrade=False)
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
1039
        repository = wt.branch.repository
2094.3.5 by John Arbash Meinel
Fix imports to ensure modules are loaded before they are used
1040
        empty = repository.revision_tree(_mod_revision.NULL_REVISION)
1551.8.37 by Aaron Bentley
Cleaner implementation of destroy_working_tree
1041
        wt.revert([], old_tree=empty)
1042
        self.destroy_workingtree_metadata()
1043
1044
    def destroy_workingtree_metadata(self):
1045
        self.transport.delete_tree('checkout')
1551.8.36 by Aaron Bentley
Introduce BzrDir.destroy_workingtree
1046
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1047
    def _get_mkdir_mode(self):
1048
        """Figure out the mode to use when creating a bzrdir subdir."""
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1049
        temp_control = lockable_files.LockableFiles(self.transport, '',
1050
                                     lockable_files.TransportLock)
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1051
        return temp_control._dir_mode
1052
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1053
    def get_branch_transport(self, branch_format):
1054
        """See BzrDir.get_branch_transport()."""
1055
        if branch_format is None:
1056
            return self.transport.clone('branch')
1057
        try:
1058
            branch_format.get_format_string()
1059
        except NotImplementedError:
1060
            raise errors.IncompatibleFormat(branch_format, self._format)
1061
        try:
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1062
            self.transport.mkdir('branch', mode=self._get_mkdir_mode())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1063
        except errors.FileExists:
1064
            pass
1065
        return self.transport.clone('branch')
1066
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
1067
    def get_repository_transport(self, repository_format):
1068
        """See BzrDir.get_repository_transport()."""
1069
        if repository_format is None:
1070
            return self.transport.clone('repository')
1071
        try:
1072
            repository_format.get_format_string()
1073
        except NotImplementedError:
1074
            raise errors.IncompatibleFormat(repository_format, self._format)
1075
        try:
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1076
            self.transport.mkdir('repository', mode=self._get_mkdir_mode())
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
1077
        except errors.FileExists:
1078
            pass
1079
        return self.transport.clone('repository')
1080
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1081
    def get_workingtree_transport(self, workingtree_format):
1082
        """See BzrDir.get_workingtree_transport()."""
1083
        if workingtree_format is None:
1084
            return self.transport.clone('checkout')
1085
        try:
1086
            workingtree_format.get_format_string()
1087
        except NotImplementedError:
1088
            raise errors.IncompatibleFormat(workingtree_format, self._format)
1089
        try:
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1090
            self.transport.mkdir('checkout', mode=self._get_mkdir_mode())
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1091
        except errors.FileExists:
1092
            pass
1093
        return self.transport.clone('checkout')
1094
1534.5.16 by Robert Collins
Review feedback.
1095
    def needs_format_conversion(self, format=None):
1096
        """See BzrDir.needs_format_conversion()."""
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1097
        if format is None:
1098
            format = BzrDirFormat.get_default_format()
1099
        if not isinstance(self._format, format.__class__):
1100
            # it is not a meta dir format, conversion is needed.
1101
            return True
1102
        # we might want to push this down to the repository?
1103
        try:
1104
            if not isinstance(self.open_repository()._format,
1105
                              format.repository_format.__class__):
1106
                # the repository needs an upgrade.
1107
                return True
1108
        except errors.NoRepositoryPresent:
1109
            pass
2230.3.29 by Aaron Bentley
Implement conversion to branch 6
1110
        try:
1111
            if not isinstance(self.open_branch()._format,
2230.3.55 by Aaron Bentley
Updates from review
1112
                              format.get_branch_format().__class__):
2255.12.1 by Robert Collins
Implement upgrade for working trees.
1113
                # the branch needs an upgrade.
1114
                return True
1115
        except errors.NotBranchError:
1116
            pass
1117
        try:
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1118
            my_wt = self.open_workingtree(recommend_upgrade=False)
1119
            if not isinstance(my_wt._format,
2255.12.1 by Robert Collins
Implement upgrade for working trees.
1120
                              format.workingtree_format.__class__):
1121
                # the workingtree needs an upgrade.
1122
                return True
2255.2.196 by Robert Collins
Fix test_upgrade defects related to non local or absent working trees.
1123
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2255.12.1 by Robert Collins
Implement upgrade for working trees.
1124
            pass
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1125
        return False
1126
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1127
    def open_branch(self, unsupported=False):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1128
        """See BzrDir.open_branch."""
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1129
        from bzrlib.branch import BranchFormat
1130
        format = BranchFormat.find_format(self)
1131
        self._check_supported(format, unsupported)
1132
        return format.open(self, _found=True)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1133
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
1134
    def open_repository(self, unsupported=False):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1135
        """See BzrDir.open_repository."""
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
1136
        from bzrlib.repository import RepositoryFormat
1137
        format = RepositoryFormat.find_format(self)
1138
        self._check_supported(format, unsupported)
1139
        return format.open(self, _found=True)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1140
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1141
    def open_workingtree(self, unsupported=False,
1142
            recommend_upgrade=True):
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1143
        """See BzrDir.open_workingtree."""
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1144
        from bzrlib.workingtree import WorkingTreeFormat
1145
        format = WorkingTreeFormat.find_format(self)
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
1146
        self._check_supported(format, unsupported,
1147
            recommend_upgrade,
2323.6.5 by Martin Pool
Recommended-upgrade message should give base dir not the control dir url
1148
            basedir=self.root_transport.base)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1149
        return format.open(self, _found=True)
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1150
1534.4.39 by Robert Collins
Basic BzrDir support.
1151
1152
class BzrDirFormat(object):
1153
    """An encapsulation of the initialization and open routines for a format.
1154
1155
    Formats provide three things:
1156
     * An initialization routine,
1157
     * a format string,
1158
     * an open routine.
1159
1160
    Formats are placed in an dict by their format string for reference 
1161
    during bzrdir opening. These should be subclasses of BzrDirFormat
1162
    for consistency.
1163
1164
    Once a format is deprecated, just deprecate the initialize and open
1165
    methods on the format class. Do not deprecate the object, as the 
1166
    object will be created every system load.
1167
    """
1168
1169
    _default_format = None
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1170
    """The default format used for new .bzr dirs."""
1534.4.39 by Robert Collins
Basic BzrDir support.
1171
1172
    _formats = {}
1173
    """The known formats."""
1174
1733.1.7 by Jelmer Vernooij
Change set of control dir formats to list.
1175
    _control_formats = []
1733.1.6 by Jelmer Vernooij
Fix a couple of minor issues after review by Martin.
1176
    """The registered control formats - .bzr, ....
1177
    
1733.1.7 by Jelmer Vernooij
Change set of control dir formats to list.
1178
    This is a list of BzrDirFormat objects.
1733.1.6 by Jelmer Vernooij
Fix a couple of minor issues after review by Martin.
1179
    """
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1180
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
1181
    _lock_file_name = 'branch-lock'
1182
1183
    # _lock_class must be set in subclasses to the lock type, typ.
1184
    # TransportLock or LockDir
1185
1534.4.39 by Robert Collins
Basic BzrDir support.
1186
    @classmethod
1187
    def find_format(klass, transport):
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1188
        """Return the format present at transport."""
1189
        for format in klass._control_formats:
1190
            try:
1191
                return format.probe_transport(transport)
1192
            except errors.NotBranchError:
1193
                # this format does not find a control dir here.
1194
                pass
1195
        raise errors.NotBranchError(path=transport.base)
1196
1197
    @classmethod
1198
    def probe_transport(klass, transport):
1199
        """Return the .bzrdir style transport present at URL."""
1534.4.39 by Robert Collins
Basic BzrDir support.
1200
        try:
2164.2.18 by Vincent Ladeuil
Take Aaron comments into account.
1201
            format_string = transport.get(".bzr/branch-format").read()
1733.2.3 by Michael Ellerman
Don't coallesce try blocks, it can lead to confusing exceptions.
1202
        except errors.NoSuchFile:
1203
            raise errors.NotBranchError(path=transport.base)
1204
1205
        try:
1534.4.39 by Robert Collins
Basic BzrDir support.
1206
            return klass._formats[format_string]
1207
        except KeyError:
1740.5.6 by Martin Pool
Clean up many exception classes.
1208
            raise errors.UnknownFormatError(format=format_string)
1534.4.39 by Robert Collins
Basic BzrDir support.
1209
1210
    @classmethod
1211
    def get_default_format(klass):
1212
        """Return the current default format."""
1213
        return klass._default_format
1214
1215
    def get_format_string(self):
1216
        """Return the ASCII format string that identifies this format."""
1217
        raise NotImplementedError(self.get_format_string)
1218
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1219
    def get_format_description(self):
1220
        """Return the short description for this format."""
1221
        raise NotImplementedError(self.get_format_description)
1222
1534.5.16 by Robert Collins
Review feedback.
1223
    def get_converter(self, format=None):
1224
        """Return the converter to use to convert bzrdirs needing converts.
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1225
1226
        This returns a bzrlib.bzrdir.Converter object.
1227
1228
        This should return the best upgrader to step this format towards the
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
1229
        current default format. In the case of plugins we can/should provide
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1230
        some means for them to extend the range of returnable converters.
1534.5.13 by Robert Collins
Correct buggy test.
1231
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
1232
        :param format: Optional format to override the default format of the 
1534.5.13 by Robert Collins
Correct buggy test.
1233
                       library.
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1234
        """
1534.5.16 by Robert Collins
Review feedback.
1235
        raise NotImplementedError(self.get_converter)
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1236
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1237
    def initialize(self, url):
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1238
        """Create a bzr control dir at this url and return an opened copy.
1239
        
1240
        Subclasses should typically override initialize_on_transport
1241
        instead of this method.
1242
        """
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1243
        return self.initialize_on_transport(get_transport(url))
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1244
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1245
    def initialize_on_transport(self, transport):
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1246
        """Initialize a new bzrdir in the base directory of a Transport."""
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
1247
        # Since we don't have a .bzr directory, inherit the
1534.4.39 by Robert Collins
Basic BzrDir support.
1248
        # mode from the root directory
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1249
        temp_control = lockable_files.LockableFiles(transport,
1250
                            '', lockable_files.TransportLock)
1534.4.39 by Robert Collins
Basic BzrDir support.
1251
        temp_control._transport.mkdir('.bzr',
1759.2.2 by Jelmer Vernooij
Revert some of my spelling fixes and fix some typos after review by Aaron.
1252
                                      # FIXME: RBC 20060121 don't peek under
1534.4.39 by Robert Collins
Basic BzrDir support.
1253
                                      # the covers
1254
                                      mode=temp_control._dir_mode)
1255
        file_mode = temp_control._file_mode
1256
        del temp_control
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1257
        mutter('created control directory in ' + transport.base)
1258
        control = transport.clone('.bzr')
1534.4.39 by Robert Collins
Basic BzrDir support.
1259
        utf8_files = [('README', 
1260
                       "This is a Bazaar-NG control directory.\n"
1261
                       "Do not change any files in this directory.\n"),
1262
                      ('branch-format', self.get_format_string()),
1263
                      ]
1264
        # NB: no need to escape relative paths that are url safe.
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1265
        control_files = lockable_files.LockableFiles(control,
1266
                            self._lock_file_name, self._lock_class)
1553.5.60 by Martin Pool
New LockableFiles.create_lock() method
1267
        control_files.create_lock()
1534.4.39 by Robert Collins
Basic BzrDir support.
1268
        control_files.lock_write()
1269
        try:
1270
            for file, content in utf8_files:
1271
                control_files.put_utf8(file, content)
1272
        finally:
1273
            control_files.unlock()
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1274
        return self.open(transport, _found=True)
1534.4.39 by Robert Collins
Basic BzrDir support.
1275
1276
    def is_supported(self):
1277
        """Is this format supported?
1278
1279
        Supported formats must be initializable and openable.
1280
        Unsupported formats may not support initialization or committing or 
1281
        some other features depending on the reason for not being supported.
1282
        """
1283
        return True
1284
1910.2.14 by Aaron Bentley
Fail when trying to use interrepository on Knit2 and Knit1
1285
    def same_model(self, target_format):
1286
        return (self.repository_format.rich_root_data == 
1287
            target_format.rich_root_data)
1288
1733.1.3 by Robert Collins
Extend the test suite to run bzrdir conformance tests on non .bzr based control dirs.
1289
    @classmethod
1290
    def known_formats(klass):
1291
        """Return all the known formats.
1292
        
1293
        Concrete formats should override _known_formats.
1294
        """
1733.1.6 by Jelmer Vernooij
Fix a couple of minor issues after review by Martin.
1295
        # There is double indirection here to make sure that control 
1296
        # formats used by more than one dir format will only be probed 
1297
        # once. This can otherwise be quite expensive for remote connections.
1733.1.3 by Robert Collins
Extend the test suite to run bzrdir conformance tests on non .bzr based control dirs.
1298
        result = set()
1299
        for format in klass._control_formats:
1300
            result.update(format._known_formats())
1301
        return result
1302
    
1303
    @classmethod
1304
    def _known_formats(klass):
1305
        """Return the known format instances for this control format."""
1306
        return set(klass._formats.values())
1307
1534.4.39 by Robert Collins
Basic BzrDir support.
1308
    def open(self, transport, _found=False):
1309
        """Return an instance of this format for the dir transport points at.
1310
        
1311
        _found is a private parameter, do not use it.
1312
        """
1313
        if not _found:
2090.2.2 by Martin Pool
Fix an assertion with side effects
1314
            found_format = BzrDirFormat.find_format(transport)
1315
            if not isinstance(found_format, self.__class__):
1316
                raise AssertionError("%s was asked to open %s, but it seems to need "
1317
                        "format %s" 
1318
                        % (self, transport, found_format))
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1319
        return self._open(transport)
1320
1321
    def _open(self, transport):
1322
        """Template method helper for opening BzrDirectories.
1323
1324
        This performs the actual open and any additional logic or parameter
1325
        passing.
1326
        """
1327
        raise NotImplementedError(self._open)
1534.4.39 by Robert Collins
Basic BzrDir support.
1328
1329
    @classmethod
1330
    def register_format(klass, format):
1331
        klass._formats[format.get_format_string()] = format
1332
1333
    @classmethod
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1334
    def register_control_format(klass, format):
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
1335
        """Register a format that does not use '.bzr' for its control dir.
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1336
1337
        TODO: This should be pulled up into a 'ControlDirFormat' base class
1338
        which BzrDirFormat can inherit from, and renamed to register_format 
1339
        there. It has been done without that for now for simplicity of
1340
        implementation.
1341
        """
1733.1.7 by Jelmer Vernooij
Change set of control dir formats to list.
1342
        klass._control_formats.append(format)
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1343
1344
    @classmethod
2204.4.12 by Aaron Bentley
Deprecate bzrdir.BzrDirFormat.set_default_format
1345
    @symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1534.4.39 by Robert Collins
Basic BzrDir support.
1346
    def set_default_format(klass, format):
2204.5.2 by Aaron Bentley
Tweak set_default_format
1347
        klass._set_default_format(format)
1534.4.39 by Robert Collins
Basic BzrDir support.
1348
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
1349
    @classmethod
1350
    def _set_default_format(klass, format):
1351
        """Set default format (for testing behavior of defaults only)"""
1352
        klass._default_format = format
1353
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
1354
    def __str__(self):
1355
        return self.get_format_string()[:-1]
1356
1534.4.39 by Robert Collins
Basic BzrDir support.
1357
    @classmethod
1358
    def unregister_format(klass, format):
1359
        assert klass._formats[format.get_format_string()] is format
1360
        del klass._formats[format.get_format_string()]
1361
1733.1.1 by Robert Collins
Support non '.bzr' control directories in bzrdir.
1362
    @classmethod
1363
    def unregister_control_format(klass, format):
1364
        klass._control_formats.remove(format)
1365
1366
1534.4.39 by Robert Collins
Basic BzrDir support.
1367
class BzrDirFormat4(BzrDirFormat):
1368
    """Bzr dir format 4.
1369
1370
    This format is a combined format for working tree, branch and repository.
1371
    It has:
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1372
     - Format 1 working trees [always]
1373
     - Format 4 branches [always]
1374
     - Format 4 repositories [always]
1534.4.39 by Robert Collins
Basic BzrDir support.
1375
1376
    This format is deprecated: it indexes texts using a text it which is
1377
    removed in format 5; write support for this format has been removed.
1378
    """
1379
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1380
    _lock_class = lockable_files.TransportLock
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
1381
1534.4.39 by Robert Collins
Basic BzrDir support.
1382
    def get_format_string(self):
1383
        """See BzrDirFormat.get_format_string()."""
1384
        return "Bazaar-NG branch, format 0.0.4\n"
1385
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1386
    def get_format_description(self):
1387
        """See BzrDirFormat.get_format_description()."""
1388
        return "All-in-one format 4"
1389
1534.5.16 by Robert Collins
Review feedback.
1390
    def get_converter(self, format=None):
1391
        """See BzrDirFormat.get_converter()."""
1534.5.13 by Robert Collins
Correct buggy test.
1392
        # there is one and only one upgrade path here.
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1393
        return ConvertBzrDir4To5()
1394
        
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1395
    def initialize_on_transport(self, transport):
1534.4.39 by Robert Collins
Basic BzrDir support.
1396
        """Format 4 branches cannot be created."""
1397
        raise errors.UninitializableFormat(self)
1398
1399
    def is_supported(self):
1400
        """Format 4 is not supported.
1401
1402
        It is not supported because the model changed from 4 to 5 and the
1403
        conversion logic is expensive - so doing it on the fly was not 
1404
        feasible.
1405
        """
1406
        return False
1407
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1408
    def _open(self, transport):
1409
        """See BzrDirFormat._open."""
1410
        return BzrDir4(transport, self)
1411
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1412
    def __return_repository_format(self):
1413
        """Circular import protection."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1414
        from bzrlib.repofmt.weaverepo import RepositoryFormat4
1910.2.12 by Aaron Bentley
Implement knit repo format 2
1415
        return RepositoryFormat4()
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1416
    repository_format = property(__return_repository_format)
1417
1534.4.39 by Robert Collins
Basic BzrDir support.
1418
1419
class BzrDirFormat5(BzrDirFormat):
1420
    """Bzr control format 5.
1421
1422
    This format is a combined format for working tree, branch and repository.
1423
    It has:
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1424
     - Format 2 working trees [always] 
1425
     - Format 4 branches [always] 
1534.4.53 by Robert Collins
Review feedback from John Meinel.
1426
     - Format 5 repositories [always]
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1427
       Unhashed stores in the repository.
1534.4.39 by Robert Collins
Basic BzrDir support.
1428
    """
1429
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1430
    _lock_class = lockable_files.TransportLock
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
1431
1534.4.39 by Robert Collins
Basic BzrDir support.
1432
    def get_format_string(self):
1433
        """See BzrDirFormat.get_format_string()."""
1434
        return "Bazaar-NG branch, format 5\n"
1435
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1436
    def get_format_description(self):
1437
        """See BzrDirFormat.get_format_description()."""
1438
        return "All-in-one format 5"
1439
1534.5.16 by Robert Collins
Review feedback.
1440
    def get_converter(self, format=None):
1441
        """See BzrDirFormat.get_converter()."""
1534.5.13 by Robert Collins
Correct buggy test.
1442
        # there is one and only one upgrade path here.
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1443
        return ConvertBzrDir5To6()
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1444
1445
    def _initialize_for_clone(self, url):
1446
        return self.initialize_on_transport(get_transport(url), _cloning=True)
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1447
        
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1448
    def initialize_on_transport(self, transport, _cloning=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1449
        """Format 5 dirs always have working tree, branch and repository.
1450
        
1451
        Except when they are being cloned.
1452
        """
1453
        from bzrlib.branch import BzrBranchFormat4
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1454
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1455
        from bzrlib.workingtree import WorkingTreeFormat2
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1456
        result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1457
        RepositoryFormat5().initialize(result, _internal=True)
1458
        if not _cloning:
1910.5.1 by Andrew Bennetts
Make some old formats create at least a stub working tree rather than incomplete bzrdirs, and change some tests to use the test suite transport rather than hard-coded to local-only.
1459
            branch = BzrBranchFormat4().initialize(result)
1460
            try:
1461
                WorkingTreeFormat2().initialize(result)
1462
            except errors.NotLocalUrl:
1463
                # Even though we can't access the working tree, we need to
1464
                # create its control files.
1465
                WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1466
        return result
1467
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1468
    def _open(self, transport):
1469
        """See BzrDirFormat._open."""
1470
        return BzrDir5(transport, self)
1471
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1472
    def __return_repository_format(self):
1473
        """Circular import protection."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1474
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1910.2.12 by Aaron Bentley
Implement knit repo format 2
1475
        return RepositoryFormat5()
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1476
    repository_format = property(__return_repository_format)
1477
1534.4.39 by Robert Collins
Basic BzrDir support.
1478
1479
class BzrDirFormat6(BzrDirFormat):
1480
    """Bzr control format 6.
1481
1482
    This format is a combined format for working tree, branch and repository.
1483
    It has:
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1484
     - Format 2 working trees [always] 
1485
     - Format 4 branches [always] 
1486
     - Format 6 repositories [always]
1534.4.39 by Robert Collins
Basic BzrDir support.
1487
    """
1488
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1489
    _lock_class = lockable_files.TransportLock
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
1490
1534.4.39 by Robert Collins
Basic BzrDir support.
1491
    def get_format_string(self):
1492
        """See BzrDirFormat.get_format_string()."""
1493
        return "Bazaar-NG branch, format 6\n"
1494
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1495
    def get_format_description(self):
1496
        """See BzrDirFormat.get_format_description()."""
1497
        return "All-in-one format 6"
1498
1534.5.16 by Robert Collins
Review feedback.
1499
    def get_converter(self, format=None):
1500
        """See BzrDirFormat.get_converter()."""
1534.5.13 by Robert Collins
Correct buggy test.
1501
        # there is one and only one upgrade path here.
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1502
        return ConvertBzrDir6ToMeta()
1503
        
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1504
    def _initialize_for_clone(self, url):
1505
        return self.initialize_on_transport(get_transport(url), _cloning=True)
1506
1608.2.8 by Martin Pool
Separate out BzrDir.initialize_on_transport so it
1507
    def initialize_on_transport(self, transport, _cloning=False):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1508
        """Format 6 dirs always have working tree, branch and repository.
1509
        
1510
        Except when they are being cloned.
1511
        """
1512
        from bzrlib.branch import BzrBranchFormat4
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1513
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1514
        from bzrlib.workingtree import WorkingTreeFormat2
1651.1.6 by Martin Pool
Clean up clone-bzrdir code
1515
        result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1516
        RepositoryFormat6().initialize(result, _internal=True)
1517
        if not _cloning:
1910.5.1 by Andrew Bennetts
Make some old formats create at least a stub working tree rather than incomplete bzrdirs, and change some tests to use the test suite transport rather than hard-coded to local-only.
1518
            branch = BzrBranchFormat4().initialize(result)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1519
            try:
1520
                WorkingTreeFormat2().initialize(result)
1521
            except errors.NotLocalUrl:
1910.5.1 by Andrew Bennetts
Make some old formats create at least a stub working tree rather than incomplete bzrdirs, and change some tests to use the test suite transport rather than hard-coded to local-only.
1522
                # Even though we can't access the working tree, we need to
1523
                # create its control files.
1524
                WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1525
        return result
1526
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1527
    def _open(self, transport):
1528
        """See BzrDirFormat._open."""
1529
        return BzrDir6(transport, self)
1530
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1531
    def __return_repository_format(self):
1532
        """Circular import protection."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1533
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1910.2.12 by Aaron Bentley
Implement knit repo format 2
1534
        return RepositoryFormat6()
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1535
    repository_format = property(__return_repository_format)
1536
1534.4.39 by Robert Collins
Basic BzrDir support.
1537
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1538
class BzrDirMetaFormat1(BzrDirFormat):
1539
    """Bzr meta control format 1
1540
1541
    This is the first format with split out working tree, branch and repository
1542
    disk storage.
1543
    It has:
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1544
     - Format 3 working trees [optional]
1545
     - Format 5 branches [optional]
1546
     - Format 7 repositories [optional]
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1547
    """
1548
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1549
    _lock_class = lockdir.LockDir
1553.5.69 by Martin Pool
BzrDirFormat subclasses can now control what kind of overall lock is used.
1550
2100.3.10 by Aaron Bentley
Ensure added references are serialized properly, beef up Workingtreee3
1551
    def __init__(self):
1552
        self._workingtree_format = None
2230.3.1 by Aaron Bentley
Get branch6 creation working
1553
        self._branch_format = None
2100.3.10 by Aaron Bentley
Ensure added references are serialized properly, beef up Workingtreee3
1554
2100.3.15 by Aaron Bentley
get test suite passing
1555
    def __eq__(self, other):
1556
        if other.__class__ is not self.__class__:
1557
            return False
1558
        if other.repository_format != self.repository_format:
1559
            return False
1560
        if other.workingtree_format != self.workingtree_format:
1561
            return False
1562
        return True
1563
2100.3.35 by Aaron Bentley
equality operations on bzrdir
1564
    def __ne__(self, other):
1565
        return not self == other
1566
2230.3.55 by Aaron Bentley
Updates from review
1567
    def get_branch_format(self):
2230.3.1 by Aaron Bentley
Get branch6 creation working
1568
        if self._branch_format is None:
1569
            from bzrlib.branch import BranchFormat
1570
            self._branch_format = BranchFormat.get_default_format()
1571
        return self._branch_format
1572
2230.3.55 by Aaron Bentley
Updates from review
1573
    def set_branch_format(self, format):
2230.3.1 by Aaron Bentley
Get branch6 creation working
1574
        self._branch_format = format
1575
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1576
    def get_converter(self, format=None):
1577
        """See BzrDirFormat.get_converter()."""
1578
        if format is None:
1579
            format = BzrDirFormat.get_default_format()
1580
        if not isinstance(self, format.__class__):
1581
            # converting away from metadir is not implemented
1582
            raise NotImplementedError(self.get_converter)
1583
        return ConvertMetaToMeta(format)
1584
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1585
    def get_format_string(self):
1586
        """See BzrDirFormat.get_format_string()."""
1587
        return "Bazaar-NG meta directory, format 1\n"
1588
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
1589
    def get_format_description(self):
1590
        """See BzrDirFormat.get_format_description()."""
1591
        return "Meta directory format 1"
1592
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1593
    def _open(self, transport):
1594
        """See BzrDirFormat._open."""
2230.3.24 by Aaron Bentley
Remove format-on-open code
1595
        return BzrDirMeta1(transport, self)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1596
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1597
    def __return_repository_format(self):
1598
        """Circular import protection."""
1599
        if getattr(self, '_repository_format', None):
1600
            return self._repository_format
1601
        from bzrlib.repository import RepositoryFormat
1602
        return RepositoryFormat.get_default_format()
1603
1604
    def __set_repository_format(self, value):
1605
        """Allow changint the repository format for metadir formats."""
1606
        self._repository_format = value
1553.5.72 by Martin Pool
Clean up test for Branch5 lockdirs
1607
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1608
    repository_format = property(__return_repository_format, __set_repository_format)
1609
2100.3.10 by Aaron Bentley
Ensure added references are serialized properly, beef up Workingtreee3
1610
    def __get_workingtree_format(self):
1611
        if self._workingtree_format is None:
1612
            from bzrlib.workingtree import WorkingTreeFormat
1613
            self._workingtree_format = WorkingTreeFormat.get_default_format()
1614
        return self._workingtree_format
1615
1616
    def __set_workingtree_format(self, wt_format):
1617
        self._workingtree_format = wt_format
1618
1619
    workingtree_format = property(__get_workingtree_format,
1620
                                  __set_workingtree_format)
1621
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
1622
2164.2.19 by Vincent Ladeuil
Revert BzrDirFormat1 registering.
1623
# Register bzr control format
1624
BzrDirFormat.register_control_format(BzrDirFormat)
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
1625
1626
# Register bzr formats
1534.4.39 by Robert Collins
Basic BzrDir support.
1627
BzrDirFormat.register_format(BzrDirFormat4())
1628
BzrDirFormat.register_format(BzrDirFormat5())
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1629
BzrDirFormat.register_format(BzrDirFormat6())
1630
__default_format = BzrDirMetaFormat1()
1534.4.39 by Robert Collins
Basic BzrDir support.
1631
BzrDirFormat.register_format(__default_format)
2204.4.13 by Aaron Bentley
Update all test cases to avoid set_default_format
1632
BzrDirFormat._default_format = __default_format
1534.4.39 by Robert Collins
Basic BzrDir support.
1633
1634
1635
class BzrDirTestProviderAdapter(object):
1636
    """A tool to generate a suite testing multiple bzrdir formats at once.
1637
1638
    This is done by copying the test once for each transport and injecting
1639
    the transport_server, transport_readonly_server, and bzrdir_format
1640
    classes into each copy. Each copy is also given a new id() to make it
1641
    easy to identify.
1642
    """
1643
1644
    def __init__(self, transport_server, transport_readonly_server, formats):
1645
        self._transport_server = transport_server
1646
        self._transport_readonly_server = transport_readonly_server
1647
        self._formats = formats
1648
    
1649
    def adapt(self, test):
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1650
        result = unittest.TestSuite()
1534.4.39 by Robert Collins
Basic BzrDir support.
1651
        for format in self._formats:
1652
            new_test = deepcopy(test)
1653
            new_test.transport_server = self._transport_server
1654
            new_test.transport_readonly_server = self._transport_readonly_server
1655
            new_test.bzrdir_format = format
1656
            def make_new_test_id():
1657
                new_id = "%s(%s)" % (new_test.id(), format.__class__.__name__)
1658
                return lambda: new_id
1659
            new_test.id = make_new_test_id()
1660
            result.addTest(new_test)
1661
        return result
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1662
1663
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1664
class Converter(object):
1665
    """Converts a disk format object from one format to another."""
1666
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1667
    def convert(self, to_convert, pb):
1668
        """Perform the conversion of to_convert, giving feedback via pb.
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1669
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1670
        :param to_convert: The disk object to convert.
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1671
        :param pb: a progress bar to use for progress information.
1672
        """
1673
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
1674
    def step(self, message):
1675
        """Update the pb by a step."""
1676
        self.count +=1
1677
        self.pb.update(message, self.count, self.total)
1678
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1679
1680
class ConvertBzrDir4To5(Converter):
1681
    """Converts format 4 bzr dirs to format 5."""
1682
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1683
    def __init__(self):
1684
        super(ConvertBzrDir4To5, self).__init__()
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1685
        self.converted_revs = set()
1686
        self.absent_revisions = set()
1687
        self.text_count = 0
1688
        self.revisions = {}
1689
        
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1690
    def convert(self, to_convert, pb):
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1691
        """See Converter.convert()."""
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1692
        self.bzrdir = to_convert
1693
        self.pb = pb
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1694
        self.pb.note('starting upgrade from format 4 to 5')
1695
        if isinstance(self.bzrdir.transport, LocalTransport):
1696
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
1697
        self._convert_to_weaves()
1698
        return BzrDir.open(self.bzrdir.root_transport.base)
1699
1700
    def _convert_to_weaves(self):
1701
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
1702
        try:
1703
            # TODO permissions
1704
            stat = self.bzrdir.transport.stat('weaves')
1705
            if not S_ISDIR(stat.st_mode):
1706
                self.bzrdir.transport.delete('weaves')
1707
                self.bzrdir.transport.mkdir('weaves')
1708
        except errors.NoSuchFile:
1709
            self.bzrdir.transport.mkdir('weaves')
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
1710
        # deliberately not a WeaveFile as we want to build it up slowly.
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1711
        self.inv_weave = Weave('inventory')
1712
        # holds in-memory weaves for all files
1713
        self.text_weaves = {}
1714
        self.bzrdir.transport.delete('branch-format')
1715
        self.branch = self.bzrdir.open_branch()
1716
        self._convert_working_inv()
1717
        rev_history = self.branch.revision_history()
1718
        # to_read is a stack holding the revisions we still need to process;
1719
        # appending to it adds new highest-priority revisions
1720
        self.known_revisions = set(rev_history)
1721
        self.to_read = rev_history[-1:]
1722
        while self.to_read:
1723
            rev_id = self.to_read.pop()
1724
            if (rev_id not in self.revisions
1725
                and rev_id not in self.absent_revisions):
1726
                self._load_one_rev(rev_id)
1727
        self.pb.clear()
1728
        to_import = self._make_order()
1729
        for i, rev_id in enumerate(to_import):
1730
            self.pb.update('converting revision', i, len(to_import))
1731
            self._convert_one_rev(rev_id)
1732
        self.pb.clear()
1733
        self._write_all_weaves()
1734
        self._write_all_revs()
1735
        self.pb.note('upgraded to weaves:')
1736
        self.pb.note('  %6d revisions and inventories', len(self.revisions))
1737
        self.pb.note('  %6d revisions not present', len(self.absent_revisions))
1738
        self.pb.note('  %6d texts', self.text_count)
1739
        self._cleanup_spare_files_after_format4()
1740
        self.branch.control_files.put_utf8('branch-format', BzrDirFormat5().get_format_string())
1741
1742
    def _cleanup_spare_files_after_format4(self):
1743
        # FIXME working tree upgrade foo.
1744
        for n in 'merged-patches', 'pending-merged-patches':
1745
            try:
1746
                ## assert os.path.getsize(p) == 0
1747
                self.bzrdir.transport.delete(n)
1748
            except errors.NoSuchFile:
1749
                pass
1750
        self.bzrdir.transport.delete_tree('inventory-store')
1751
        self.bzrdir.transport.delete_tree('text-store')
1752
1753
    def _convert_working_inv(self):
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
1754
        inv = xml4.serializer_v4.read_inventory(
1755
                    self.branch.control_files.get('inventory'))
1756
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1757
        # FIXME inventory is a working tree change.
1955.3.4 by John Arbash Meinel
Fix 2 calls to 'put()' that were using strings instead of files
1758
        self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1759
1760
    def _write_all_weaves(self):
1761
        controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
1762
        weave_transport = self.bzrdir.transport.clone('weaves')
1763
        weaves = WeaveStore(weave_transport, prefixed=False)
1563.2.34 by Robert Collins
Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction
1764
        transaction = WriteTransaction()
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1765
1766
        try:
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
1767
            i = 0
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1768
            for file_id, file_weave in self.text_weaves.items():
1769
                self.pb.update('writing weave', i, len(self.text_weaves))
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
1770
                weaves._put_weave(file_id, file_weave, transaction)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1771
                i += 1
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
1772
            self.pb.update('inventory', 0, 1)
1773
            controlweaves._put_weave('inventory', self.inv_weave, transaction)
1774
            self.pb.update('inventory', 1, 1)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1775
        finally:
1776
            self.pb.clear()
1777
1778
    def _write_all_revs(self):
1779
        """Write all revisions out in new form."""
1780
        self.bzrdir.transport.delete_tree('revision-store')
1781
        self.bzrdir.transport.mkdir('revision-store')
1782
        revision_transport = self.bzrdir.transport.clone('revision-store')
1783
        # TODO permissions
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
1784
        _revision_store = TextRevisionStore(TextStore(revision_transport,
1785
                                                      prefixed=False,
1786
                                                      compressed=True))
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1787
        try:
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
1788
            transaction = WriteTransaction()
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1789
            for i, rev_id in enumerate(self.converted_revs):
1790
                self.pb.update('write revision', i, len(self.converted_revs))
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
1791
                _revision_store.add_revision(self.revisions[rev_id], transaction)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1792
        finally:
1793
            self.pb.clear()
1794
            
1795
    def _load_one_rev(self, rev_id):
1796
        """Load a revision object into memory.
1797
1798
        Any parents not either loaded or abandoned get queued to be
1799
        loaded."""
1800
        self.pb.update('loading revision',
1801
                       len(self.revisions),
1802
                       len(self.known_revisions))
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
1803
        if not self.branch.repository.has_revision(rev_id):
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1804
            self.pb.clear()
1805
            self.pb.note('revision {%s} not present in branch; '
1806
                         'will be converted as a ghost',
1807
                         rev_id)
1808
            self.absent_revisions.add(rev_id)
1809
        else:
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
1810
            rev = self.branch.repository._revision_store.get_revision(rev_id,
1811
                self.branch.repository.get_transaction())
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1812
            for parent_id in rev.parent_ids:
1813
                self.known_revisions.add(parent_id)
1814
                self.to_read.append(parent_id)
1815
            self.revisions[rev_id] = rev
1816
1817
    def _load_old_inventory(self, rev_id):
1818
        assert rev_id not in self.converted_revs
1819
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
1820
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
1910.2.36 by Aaron Bentley
Get upgrade from format4 under test and fixed for all formats
1821
        inv.revision_id = rev_id
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1822
        rev = self.revisions[rev_id]
1823
        if rev.inventory_sha1:
1824
            assert rev.inventory_sha1 == sha_string(old_inv_xml), \
1825
                'inventory sha mismatch for {%s}' % rev_id
1826
        return inv
1827
1828
    def _load_updated_inventory(self, rev_id):
1829
        assert rev_id in self.converted_revs
1830
        inv_xml = self.inv_weave.get_text(rev_id)
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
1831
        inv = xml5.serializer_v5.read_inventory_from_string(inv_xml)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1832
        return inv
1833
1834
    def _convert_one_rev(self, rev_id):
1835
        """Convert revision and all referenced objects to new format."""
1836
        rev = self.revisions[rev_id]
1837
        inv = self._load_old_inventory(rev_id)
1838
        present_parents = [p for p in rev.parent_ids
1839
                           if p not in self.absent_revisions]
1840
        self._convert_revision_contents(rev, inv, present_parents)
1841
        self._store_new_weave(rev, inv, present_parents)
1842
        self.converted_revs.add(rev_id)
1843
1844
    def _store_new_weave(self, rev, inv, present_parents):
1845
        # the XML is now updated with text versions
1846
        if __debug__:
1907.1.8 by Aaron Bentley
Remove is_root
1847
            entries = inv.iter_entries()
1848
            entries.next()
1849
            for path, ie in entries:
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
1850
                assert getattr(ie, 'revision', None) is not None, \
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1851
                    'no revision on {%s} in {%s}' % \
1852
                    (file_id, rev.revision_id)
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
1853
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1854
        new_inv_sha1 = sha_string(new_inv_xml)
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
1855
        self.inv_weave.add_lines(rev.revision_id, 
1856
                                 present_parents,
1857
                                 new_inv_xml.splitlines(True))
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1858
        rev.inventory_sha1 = new_inv_sha1
1859
1860
    def _convert_revision_contents(self, rev, inv, present_parents):
1861
        """Convert all the files within a revision.
1862
1863
        Also upgrade the inventory to refer to the text revision ids."""
1864
        rev_id = rev.revision_id
1865
        mutter('converting texts of revision {%s}',
1866
               rev_id)
1867
        parent_invs = map(self._load_updated_inventory, present_parents)
1731.1.62 by Aaron Bentley
Changes from review comments
1868
        entries = inv.iter_entries()
1869
        entries.next()
1870
        for path, ie in entries:
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1871
            self._convert_file_version(rev, ie, parent_invs)
1872
1873
    def _convert_file_version(self, rev, ie, parent_invs):
1874
        """Convert one version of one file.
1875
1876
        The file needs to be added into the weave if it is a merge
1877
        of >=2 parents or if it's changed from its parent.
1878
        """
1879
        file_id = ie.file_id
1880
        rev_id = rev.revision_id
1881
        w = self.text_weaves.get(file_id)
1882
        if w is None:
1883
            w = Weave(file_id)
1884
            self.text_weaves[file_id] = w
1885
        text_changed = False
1596.2.20 by Robert Collins
optimise commit to only access weaves for merged, or altered files during commit.
1886
        previous_entries = ie.find_previous_heads(parent_invs,
1887
                                                  None,
1888
                                                  None,
1889
                                                  entry_vf=w)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1890
        for old_revision in previous_entries:
1891
                # if this fails, its a ghost ?
1731.1.33 by Aaron Bentley
Revert no-special-root changes
1892
                assert old_revision in self.converted_revs, \
1893
                    "Revision {%s} not in converted_revs" % old_revision
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1894
        self.snapshot_ie(previous_entries, ie, w, rev_id)
1895
        del ie.text_id
1896
        assert getattr(ie, 'revision', None) is not None
1897
1898
    def snapshot_ie(self, previous_revisions, ie, w, rev_id):
1899
        # TODO: convert this logic, which is ~= snapshot to
1900
        # a call to:. This needs the path figured out. rather than a work_tree
1901
        # a v4 revision_tree can be given, or something that looks enough like
1902
        # one to give the file content to the entry if it needs it.
1903
        # and we need something that looks like a weave store for snapshot to 
1904
        # save against.
1905
        #ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
1906
        if len(previous_revisions) == 1:
1907
            previous_ie = previous_revisions.values()[0]
1908
            if ie._unchanged(previous_ie):
1909
                ie.revision = previous_ie.revision
1910
                return
1911
        if ie.has_text():
1912
            text = self.branch.repository.text_store.get(ie.text_id)
1913
            file_lines = text.readlines()
1914
            assert sha_strings(file_lines) == ie.text_sha1
1915
            assert sum(map(len, file_lines)) == ie.text_size
1563.2.18 by Robert Collins
get knit repositories really using knits for text storage.
1916
            w.add_lines(rev_id, previous_revisions, file_lines)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1917
            self.text_count += 1
1918
        else:
1563.2.18 by Robert Collins
get knit repositories really using knits for text storage.
1919
            w.add_lines(rev_id, previous_revisions, [])
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1920
        ie.revision = rev_id
1921
1922
    def _make_order(self):
1923
        """Return a suitable order for importing revisions.
1924
1925
        The order must be such that an revision is imported after all
1926
        its (present) parents.
1927
        """
1928
        todo = set(self.revisions.keys())
1929
        done = self.absent_revisions.copy()
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1930
        order = []
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1931
        while todo:
1932
            # scan through looking for a revision whose parents
1933
            # are all done
1934
            for rev_id in sorted(list(todo)):
1935
                rev = self.revisions[rev_id]
1936
                parent_ids = set(rev.parent_ids)
1937
                if parent_ids.issubset(done):
1938
                    # can take this one now
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1939
                    order.append(rev_id)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1940
                    todo.remove(rev_id)
1941
                    done.add(rev_id)
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1942
        return order
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1943
1944
1945
class ConvertBzrDir5To6(Converter):
1946
    """Converts format 5 bzr dirs to format 6."""
1947
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1948
    def convert(self, to_convert, pb):
1949
        """See Converter.convert()."""
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1950
        self.bzrdir = to_convert
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1951
        self.pb = pb
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1952
        self.pb.note('starting upgrade from format 5 to 6')
1953
        self._convert_to_prefixed()
1954
        return BzrDir.open(self.bzrdir.root_transport.base)
1955
1956
    def _convert_to_prefixed(self):
1608.2.1 by Martin Pool
[merge] Storage filename escaping
1957
        from bzrlib.store import TransportStore
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1958
        self.bzrdir.transport.delete('branch-format')
1959
        for store_name in ["weaves", "revision-store"]:
1608.2.1 by Martin Pool
[merge] Storage filename escaping
1960
            self.pb.note("adding prefixes to %s" % store_name)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1961
            store_transport = self.bzrdir.transport.clone(store_name)
1608.2.1 by Martin Pool
[merge] Storage filename escaping
1962
            store = TransportStore(store_transport, prefixed=True)
1608.1.1 by Martin Pool
[patch] LocalTransport.list_dir should return url-quoted strings (ddaa)
1963
            for urlfilename in store_transport.list_dir('.'):
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
1964
                filename = urlutils.unescape(urlfilename)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1965
                if (filename.endswith(".weave") or
1966
                    filename.endswith(".gz") or
1967
                    filename.endswith(".sig")):
1968
                    file_id = os.path.splitext(filename)[0]
1969
                else:
1970
                    file_id = filename
1608.2.1 by Martin Pool
[merge] Storage filename escaping
1971
                prefix_dir = store.hash_prefix(file_id)
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1972
                # FIXME keep track of the dirs made RBC 20060121
1973
                try:
1974
                    store_transport.move(filename, prefix_dir + '/' + filename)
1975
                except errors.NoSuchFile: # catches missing dirs strangely enough
1976
                    store_transport.mkdir(prefix_dir)
1977
                    store_transport.move(filename, prefix_dir + '/' + filename)
1978
        self.bzrdir._control_files.put_utf8('branch-format', BzrDirFormat6().get_format_string())
1979
1980
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1981
class ConvertBzrDir6ToMeta(Converter):
1982
    """Converts format 6 bzr dirs to metadirs."""
1983
1984
    def convert(self, to_convert, pb):
1985
        """See Converter.convert()."""
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
1986
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2094.3.5 by John Arbash Meinel
Fix imports to ensure modules are loaded before they are used
1987
        from bzrlib.branch import BzrBranchFormat5
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
1988
        self.bzrdir = to_convert
1989
        self.pb = pb
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1990
        self.count = 0
1991
        self.total = 20 # the steps we know about
1992
        self.garbage_inventories = []
1993
1534.5.13 by Robert Collins
Correct buggy test.
1994
        self.pb.note('starting upgrade from format 6 to metadir')
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
1995
        self.bzrdir._control_files.put_utf8('branch-format', "Converting to format 6")
1996
        # its faster to move specific files around than to open and use the apis...
1997
        # first off, nuke ancestry.weave, it was never used.
1998
        try:
1999
            self.step('Removing ancestry.weave')
2000
            self.bzrdir.transport.delete('ancestry.weave')
2001
        except errors.NoSuchFile:
2002
            pass
2003
        # find out whats there
2004
        self.step('Finding branch files')
1666.1.3 by Robert Collins
Fix and test upgrades from bzrdir 6 over SFTP.
2005
        last_revision = self.bzrdir.open_branch().last_revision()
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2006
        bzrcontents = self.bzrdir.transport.list_dir('.')
2007
        for name in bzrcontents:
2008
            if name.startswith('basis-inventory.'):
2009
                self.garbage_inventories.append(name)
2010
        # create new directories for repository, working tree and branch
1553.5.79 by Martin Pool
upgrade to metadir should create LockDirs not files
2011
        self.dir_mode = self.bzrdir._control_files._dir_mode
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2012
        self.file_mode = self.bzrdir._control_files._file_mode
2013
        repository_names = [('inventory.weave', True),
2014
                            ('revision-store', True),
2015
                            ('weaves', True)]
2016
        self.step('Upgrading repository  ')
1553.5.79 by Martin Pool
upgrade to metadir should create LockDirs not files
2017
        self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2018
        self.make_lock('repository')
2019
        # we hard code the formats here because we are converting into
2020
        # the meta format. The meta format upgrader can take this to a 
2021
        # future format within each component.
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
2022
        self.put_format('repository', RepositoryFormat7())
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2023
        for entry in repository_names:
2024
            self.move_entry('repository', entry)
2025
2026
        self.step('Upgrading branch      ')
1553.5.79 by Martin Pool
upgrade to metadir should create LockDirs not files
2027
        self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2028
        self.make_lock('branch')
2094.3.5 by John Arbash Meinel
Fix imports to ensure modules are loaded before they are used
2029
        self.put_format('branch', BzrBranchFormat5())
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2030
        branch_files = [('revision-history', True),
2031
                        ('branch-name', True),
2032
                        ('parent', False)]
2033
        for entry in branch_files:
2034
            self.move_entry('branch', entry)
2035
2036
        checkout_files = [('pending-merges', True),
2037
                          ('inventory', True),
2038
                          ('stat-cache', False)]
1959.3.1 by John Arbash Meinel
David Allouche: bzr upgrade should work if there is no working tree
2039
        # If a mandatory checkout file is not present, the branch does not have
2040
        # a functional checkout. Do not create a checkout in the converted
2041
        # branch.
2042
        for name, mandatory in checkout_files:
2043
            if mandatory and name not in bzrcontents:
2044
                has_checkout = False
2045
                break
2046
        else:
2047
            has_checkout = True
2048
        if not has_checkout:
2049
            self.pb.note('No working tree.')
2050
            # If some checkout files are there, we may as well get rid of them.
2051
            for name, mandatory in checkout_files:
2052
                if name in bzrcontents:
2053
                    self.bzrdir.transport.delete(name)
2054
        else:
2123.2.1 by John Arbash Meinel
Fix bug #70716, make bzrlib.bzrdir directly import bzrlib.workingtree
2055
            from bzrlib.workingtree import WorkingTreeFormat3
1959.3.1 by John Arbash Meinel
David Allouche: bzr upgrade should work if there is no working tree
2056
            self.step('Upgrading working tree')
2057
            self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2058
            self.make_lock('checkout')
2059
            self.put_format(
2123.2.1 by John Arbash Meinel
Fix bug #70716, make bzrlib.bzrdir directly import bzrlib.workingtree
2060
                'checkout', WorkingTreeFormat3())
1959.3.1 by John Arbash Meinel
David Allouche: bzr upgrade should work if there is no working tree
2061
            self.bzrdir.transport.delete_multi(
2062
                self.garbage_inventories, self.pb)
2063
            for entry in checkout_files:
2064
                self.move_entry('checkout', entry)
2065
            if last_revision is not None:
2066
                self.bzrdir._control_files.put_utf8(
2067
                    'checkout/last-revision', last_revision)
2068
        self.bzrdir._control_files.put_utf8(
2069
            'branch-format', BzrDirMetaFormat1().get_format_string())
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
2070
        return BzrDir.open(self.bzrdir.root_transport.base)
2071
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2072
    def make_lock(self, name):
2073
        """Make a lock for the new control dir name."""
2074
        self.step('Make %s lock' % name)
1996.3.3 by John Arbash Meinel
Shave off another 40ms by demand loading branch and bzrdir
2075
        ld = lockdir.LockDir(self.bzrdir.transport,
2076
                             '%s/lock' % name,
2077
                             file_modebits=self.file_mode,
2078
                             dir_modebits=self.dir_mode)
1553.5.79 by Martin Pool
upgrade to metadir should create LockDirs not files
2079
        ld.create()
1534.5.11 by Robert Collins
Implement upgrades to Metaformat trees.
2080
2081
    def move_entry(self, new_dir, entry):
2082
        """Move then entry name into new_dir."""
2083
        name = entry[0]
2084
        mandatory = entry[1]
2085
        self.step('Moving %s' % name)
2086
        try:
2087
            self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2088
        except errors.NoSuchFile:
2089
            if mandatory:
2090
                raise
2091
2092
    def put_format(self, dirname, format):
2093
        self.bzrdir._control_files.put_utf8('%s/format' % dirname, format.get_format_string())
2094
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
2095
2096
class ConvertMetaToMeta(Converter):
2097
    """Converts the components of metadirs."""
2098
2099
    def __init__(self, target_format):
2100
        """Create a metadir to metadir converter.
2101
2102
        :param target_format: The final metadir format that is desired.
2103
        """
2104
        self.target_format = target_format
2105
2106
    def convert(self, to_convert, pb):
2107
        """See Converter.convert()."""
2108
        self.bzrdir = to_convert
2109
        self.pb = pb
2110
        self.count = 0
2111
        self.total = 1
2112
        self.step('checking repository format')
2113
        try:
2114
            repo = self.bzrdir.open_repository()
2115
        except errors.NoRepositoryPresent:
2116
            pass
2117
        else:
2118
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
2119
                from bzrlib.repository import CopyConverter
2120
                self.pb.note('starting repository conversion')
2121
                converter = CopyConverter(self.target_format.repository_format)
2122
                converter.convert(repo, pb)
2230.3.29 by Aaron Bentley
Implement conversion to branch 6
2123
        try:
2124
            branch = self.bzrdir.open_branch()
2125
        except errors.NotBranchError:
2126
            pass
2127
        else:
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2128
            # TODO: conversions of Branch and Tree should be done by
2129
            # InterXFormat lookups
2230.3.29 by Aaron Bentley
Implement conversion to branch 6
2130
            # Avoid circular imports
2131
            from bzrlib import branch as _mod_branch
2132
            if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
2230.3.55 by Aaron Bentley
Updates from review
2133
                self.target_format.get_branch_format().__class__ is
2230.3.29 by Aaron Bentley
Implement conversion to branch 6
2134
                _mod_branch.BzrBranchFormat6):
2135
                branch_converter = _mod_branch.Converter5to6()
2136
                branch_converter.convert(branch)
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2137
        try:
2323.6.4 by Martin Pool
BzrDir._check_supported now also takes care of recommending upgrades, which
2138
            tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2255.2.196 by Robert Collins
Fix test_upgrade defects related to non local or absent working trees.
2139
        except (errors.NoWorkingTree, errors.NotLocalUrl):
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2140
            pass
2141
        else:
2142
            # TODO: conversions of Branch and Tree should be done by
2143
            # InterXFormat lookups
2144
            if (isinstance(tree, workingtree.WorkingTree3) and
2255.2.212 by Robert Collins
Fix upgrade bug exposed via repository tests, dont replace dirstate format trees during upgrade.
2145
                not isinstance(tree, workingtree_4.WorkingTree4) and
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2146
                isinstance(self.target_format.workingtree_format,
2147
                    workingtree_4.WorkingTreeFormat4)):
2148
                workingtree_4.Converter3to4().convert(tree)
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
2149
        return to_convert
1731.2.18 by Aaron Bentley
Get extract in repository under test
2150
2151
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2152
class BzrDirFormatInfo(object):
2153
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2154
    def __init__(self, native, deprecated, hidden):
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2155
        self.deprecated = deprecated
2156
        self.native = native
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2157
        self.hidden = hidden
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2158
2159
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2160
class BzrDirFormatRegistry(registry.Registry):
2161
    """Registry of user-selectable BzrDir subformats.
2162
    
2163
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2164
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
2165
    """
2166
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2167
    def register_metadir(self, key,
2168
             repository_format, help, native=True, deprecated=False,
2169
             branch_format=None,
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2170
             tree_format=None,
2171
             hidden=False):
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2172
        """Register a metadir subformat.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
2173
2174
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2175
        by the Repository format.
2176
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2177
        :param repository_format: The fully-qualified repository format class
2178
            name as a string.
2179
        :param branch_format: Fully-qualified branch format class name as
2180
            a string.
2181
        :param tree_format: Fully-qualified tree format class name as
2182
            a string.
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2183
        """
2184
        # This should be expanded to support setting WorkingTree and Branch
2185
        # formats, once BzrDirMetaFormat1 supports that.
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2186
        def _load(full_name):
2187
            mod_name, factory_name = full_name.rsplit('.', 1)
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
2188
            try:
2189
                mod = __import__(mod_name, globals(), locals(),
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2190
                        [factory_name])
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
2191
            except ImportError, e:
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2192
                raise ImportError('failed to load %s: %s' % (full_name, e))
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
2193
            try:
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2194
                factory = getattr(mod, factory_name)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
2195
            except AttributeError:
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2196
                raise AttributeError('no factory %s in module %r'
2197
                    % (full_name, mod))
2198
            return factory()
2199
2200
        def helper():
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2201
            bd = BzrDirMetaFormat1()
2230.3.1 by Aaron Bentley
Get branch6 creation working
2202
            if branch_format is not None:
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
2203
                bd.set_branch_format(_load(branch_format))
2204
            if tree_format is not None:
2205
                bd.workingtree_format = _load(tree_format)
2206
            if repository_format is not None:
2207
                bd.repository_format = _load(repository_format)
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2208
            return bd
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2209
        self.register(key, helper, help, native, deprecated, hidden)
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2210
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2211
    def register(self, key, factory, help, native=True, deprecated=False,
2212
                 hidden=False):
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2213
        """Register a BzrDirFormat factory.
2214
        
2215
        The factory must be a callable that takes one parameter: the key.
2216
        It must produce an instance of the BzrDirFormat when called.
2217
2218
        This function mainly exists to prevent the info object from being
2219
        supplied directly.
2220
        """
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2221
        registry.Registry.register(self, key, factory, help, 
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2222
            BzrDirFormatInfo(native, deprecated, hidden))
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2223
2204.4.7 by Aaron Bentley
restore register_lazy, remove register_factory, other updates
2224
    def register_lazy(self, key, module_name, member_name, help, native=True,
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2225
                      deprecated=False, hidden=False):
2204.4.7 by Aaron Bentley
restore register_lazy, remove register_factory, other updates
2226
        registry.Registry.register_lazy(self, key, module_name, member_name, 
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2227
            help, BzrDirFormatInfo(native, deprecated, hidden))
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2228
2229
    def set_default(self, key):
2230
        """Set the 'default' key to be a clone of the supplied key.
2231
        
2232
        This method must be called once and only once.
2233
        """
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2234
        registry.Registry.register(self, 'default', self.get(key), 
2235
            self.get_help(key), info=self.get_info(key))
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2236
2204.4.11 by Aaron Bentley
deprecate Repository.set_default_format, update upgrade tests
2237
    def set_default_repository(self, key):
2238
        """Set the FormatRegistry default and Repository default.
2239
        
2240
        This is a transitional method while Repository.set_default_format
2241
        is deprecated.
2242
        """
2243
        if 'default' in self:
2244
            self.remove('default')
2245
        self.set_default(key)
2246
        format = self.get('default')()
2247
        assert isinstance(format, BzrDirMetaFormat1)
2248
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2249
    def make_bzrdir(self, key):
2204.4.7 by Aaron Bentley
restore register_lazy, remove register_factory, other updates
2250
        return self.get(key)()
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2251
2252
    def help_topic(self, topic):
2253
        output = textwrap.dedent("""\
2254
            Bazaar directory formats
2255
            ------------------------
2256
2257
            These formats can be used for creating branches, working trees, and
2258
            repositories.
2204.4.2 by Aaron Bentley
Tweak topic appearance
2259
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2260
            """)
2261
        default_help = self.get_help('default')
2262
        help_pairs = []
2263
        for key in self.keys():
2264
            if key == 'default':
2265
                continue
2266
            help = self.get_help(key)
2267
            if help == default_help:
2268
                default_realkey = key
2269
            else:
2270
                help_pairs.append((key, help))
2271
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2272
        def wrapped(key, help, info):
2273
            if info.native:
2274
                help = '(native) ' + help
2204.4.2 by Aaron Bentley
Tweak topic appearance
2275
            return '  %s:\n%s\n\n' % (key, 
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2276
                    textwrap.fill(help, initial_indent='    ', 
2277
                    subsequent_indent='    '))
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2278
        output += wrapped('%s/default' % default_realkey, default_help,
2279
                          self.get_info('default'))
2280
        deprecated_pairs = []
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2281
        for key, help in help_pairs:
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2282
            info = self.get_info(key)
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2283
            if info.hidden:
2284
                continue
2285
            elif info.deprecated:
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2286
                deprecated_pairs.append((key, help))
2287
            else:
2288
                output += wrapped(key, help, info)
2289
        if len(deprecated_pairs) > 0:
2290
            output += "Deprecated formats\n------------------\n\n"
2291
            for key, help in deprecated_pairs:
2292
                info = self.get_info(key)
2293
                output += wrapped(key, help, info)
2294
2204.4.1 by Aaron Bentley
Add 'formats' help topic
2295
        return output
2296
2297
2298
format_registry = BzrDirFormatRegistry()
2204.4.7 by Aaron Bentley
restore register_lazy, remove register_factory, other updates
2299
format_registry.register('weave', BzrDirFormat6,
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2300
    'Pre-0.8 format.  Slower than knit and does not'
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
2301
    ' support checkouts or shared repositories.',
2302
    deprecated=True)
2303
format_registry.register_metadir('knit',
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
2304
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2305
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
2306
    branch_format='bzrlib.branch.BzrBranchFormat5',
2255.2.199 by Robert Collins
Fix definition of knit format; typos are not good.
2307
    tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
2308
format_registry.register_metadir('metaweave',
2309
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2230.3.30 by Aaron Bentley
Fix whitespace issues
2310
    'Transitional format in 0.8.  Slower than knit.',
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2311
    branch_format='bzrlib.branch.BzrBranchFormat5',
2255.2.209 by Robert Collins
Remove circular imports in bzrdir format definitions.
2312
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2204.4.4 by Aaron Bentley
Use BzrDirFormatInfo to distinguish native and deprecated formats
2313
    deprecated=True)
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2314
format_registry.register_metadir('dirstate',
2315
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2316
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2317
        'above when accessed over the network.',
2318
    branch_format='bzrlib.branch.BzrBranchFormat5',
2255.2.209 by Robert Collins
Remove circular imports in bzrdir format definitions.
2319
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2320
    # directly from workingtree_4 triggers a circular import.
2321
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2322
    )
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
2323
format_registry.register_metadir('dirstate-tags',
2324
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2325
    help='New in 0.15: Fast local operations and improved scaling for '
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2326
        'network operations. Additionally adds support for tags.'
2327
        ' Incompatible with bzr < 0.15.',
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
2328
    branch_format='bzrlib.branch.BzrBranchFormat6',
2329
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2330
    )
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2331
format_registry.register_metadir('dirstate-with-subtree',
2332
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2333
    help='New in 0.15: Fast local operations and improved scaling for '
2334
        'network operations. Additionally adds support for versioning nested '
2335
        'bzr branches. Incompatible with bzr < 0.15.',
2336
    branch_format='bzrlib.branch.BzrBranchFormat6',
2255.2.209 by Robert Collins
Remove circular imports in bzrdir format definitions.
2337
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
2338
    hidden=True,
2255.12.1 by Robert Collins
Implement upgrade for working trees.
2339
    )
2255.2.209 by Robert Collins
Remove circular imports in bzrdir format definitions.
2340
format_registry.set_default('dirstate')