~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2005, 2006, 2008-2011 Canonical Ltd
1267 by Martin Pool
- notes on conversion of existing history to weaves
2
#
1080 by Martin Pool
- test tool for converting history to weave files
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.
1267 by Martin Pool
- notes on conversion of existing history to weaves
7
#
1080 by Martin Pool
- test tool for converting history to weave files
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.
1267 by Martin Pool
- notes on conversion of existing history to weaves
12
#
1080 by Martin Pool
- test tool for converting history to weave files
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1080 by Martin Pool
- test tool for converting history to weave files
16
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
17
"""bzr upgrade logic."""
18
3943.2.1 by Martin Pool
doc/import cleanups
19
4360.10.40 by Vincent Ladeuil
Fix imports ;)
20
from bzrlib import (
21
    errors,
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
22
    trace,
4360.10.40 by Vincent Ladeuil
Fix imports ;)
23
    ui,
24
    )
5582.10.8 by Jelmer Vernooij
More fixes.
25
from bzrlib.bzrdir import (
26
    BzrDir,
27
    format_registry,
28
    )
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
29
from bzrlib.remote import RemoteBzrDir
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
30
31
32
class Convert(object):
33
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
34
    def __init__(self, url=None, format=None, control_dir=None):
35
        """Convert a Bazaar control directory to a given format.
36
37
        Either the url or control_dir parameter must be given.
38
39
        :param url: the URL of the control directory or None if the
40
          control_dir is explicitly given instead
41
        :param format: the format to convert to or None for the default
4360.10.10 by Ian Clatworthy
minor clean-ups
42
        :param control_dir: the control directory or None if it is
43
          specified via the URL parameter instead
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
44
        """
1534.5.13 by Robert Collins
Correct buggy test.
45
        self.format = format
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
46
        # XXX: Change to cleanup
47
        warning_id = 'cross_format_fetch'
4634.144.11 by Martin Pool
Rename squelched to suppressed
48
        saved_warning = warning_id in ui.ui_factory.suppressed_warnings
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
49
        if url is None and control_dir is None:
50
            raise AssertionError(
51
                "either the url or control_dir parameter must be set.")
52
        if control_dir is not None:
53
            self.bzrdir = control_dir
54
        else:
55
            self.bzrdir = BzrDir.open_unsupported(url)
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
56
        if isinstance(self.bzrdir, RemoteBzrDir):
57
            self.bzrdir._ensure_real()
58
            self.bzrdir = self.bzrdir._real_bzrdir
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
59
        if self.bzrdir.root_transport.is_readonly():
60
            raise errors.UpgradeReadonly
61
        self.transport = self.bzrdir.root_transport
4634.144.11 by Martin Pool
Rename squelched to suppressed
62
        ui.ui_factory.suppressed_warnings.add(warning_id)
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
63
        try:
64
            self.convert()
65
        finally:
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
66
            if not saved_warning:
4634.144.11 by Martin Pool
Rename squelched to suppressed
67
                ui.ui_factory.suppressed_warnings.remove(warning_id)
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
68
69
    def convert(self):
1558.7.2 by Aaron Bentley
Upgrade works in repositories
70
        try:
71
            branch = self.bzrdir.open_branch()
5158.6.9 by Martin Pool
Simplify various code to use user_url
72
            if branch.user_url != self.bzrdir.user_url:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
73
                ui.ui_factory.note(
74
                    'This is a checkout. The branch (%s) needs to be upgraded'
75
                    ' separately.' % (branch.user_url,))
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
76
            del branch
77
        except (errors.NotBranchError, errors.IncompatibleRepositories):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
78
            # might not be a format we can open without upgrading; see e.g.
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
79
            # https://bugs.launchpad.net/bzr/+bug/253891
1558.7.2 by Aaron Bentley
Upgrade works in repositories
80
            pass
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
81
        if self.format is None:
4170.3.5 by Jelmer Vernooij
Fix upgrade if there is no local repository present.
82
            try:
83
                rich_root = self.bzrdir.find_repository()._format.rich_root_data
84
            except errors.NoRepositoryPresent:
85
                rich_root = False # assume no rich roots
86
            if rich_root:
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
87
                format_name = "default-rich-root"
88
            else:
89
                format_name = "default"
90
            format = format_registry.make_bzrdir(format_name)
91
        else:
92
            format = self.format
93
        if not self.bzrdir.needs_format_conversion(format):
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
94
            raise errors.UpToDateFormat(self.bzrdir._format)
1534.5.16 by Robert Collins
Review feedback.
95
        if not self.bzrdir.can_convert_format():
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
96
            raise errors.BzrError("cannot upgrade from bzrdir format %s" %
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
97
                           self.bzrdir._format)
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
98
        self.bzrdir.check_conversion_target(format)
4471.2.2 by Martin Pool
Deprecate ProgressTask.note
99
        ui.ui_factory.note('starting upgrade of %s' % self.transport.base)
100
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
101
        self.backup_oldpath, self.backup_newpath = self.bzrdir.backup_bzrdir()
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
102
        while self.bzrdir.needs_format_conversion(format):
103
            converter = self.bzrdir._format.get_converter(format)
4961.2.15 by Martin Pool
Remove more pb-passing
104
            self.bzrdir = converter.convert(self.bzrdir, None)
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
105
        ui.ui_factory.note('finished')
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
106
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
107
    def clean_up(self):
108
        """Clean-up after a conversion.
109
110
        This removes the backup.bzr directory.
111
        """
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
112
        transport = self.transport
113
        backup_relpath = transport.relpath(self.backup_newpath)
4360.10.27 by Matthew Fuller
Wrap a progress bar around removing the backup dir; it may take a
114
        child_pb = ui.ui_factory.nested_progress_bar()
115
        child_pb.update('Deleting backup.bzr')
116
        try:
117
            transport.delete_tree(backup_relpath)
118
        finally:
119
            child_pb.finished()
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
120
121
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
122
def upgrade(url, format=None, clean_up=False, dry_run=False):
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
123
    """Upgrade locations to format.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
124
 
125
    This routine wraps the smart_upgrade() routine with a nicer UI.
126
    In particular, it ensures all URLs can be opened before starting
127
    and reports a summary at the end if more than one upgrade was attempted.
128
    This routine is useful for command line tools. Other bzrlib clients
129
    probably ought to use smart_upgrade() instead.
130
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
131
    :param url: a URL of the locations to upgrade.
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
132
    :param format: the format to convert to or None for the best default
133
    :param clean-up: if True, the backup.bzr directory is removed if the
134
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
135
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
136
    :return: the list of exceptions encountered
137
    """
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
138
    control_dirs = [BzrDir.open_unsupported(url)]
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
139
    attempted, succeeded, exceptions = smart_upgrade(control_dirs,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
140
        format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
141
    if len(attempted) > 1:
142
        attempted_count = len(attempted)
143
        succeeded_count = len(succeeded)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
144
        failed_count = attempted_count - succeeded_count
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
145
        ui.ui_factory.note(
146
            '\nSUMMARY: %d upgrades attempted, %d succeeded, %d failed'
147
            % (attempted_count, succeeded_count, failed_count))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
148
    return exceptions
149
150
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
151
def smart_upgrade(control_dirs, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
152
    dry_run=False):
153
    """Convert control directories to a new format intelligently.
154
155
    If the control directory is a shared repository, dependent branches
156
    are also converted provided the repository converted successfully.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
157
    If the conversion of a branch fails, remaining branches are still tried.
158
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
159
    :param control_dirs: the BzrDirs to upgrade
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
160
    :param format: the format to convert to or None for the best default
4360.10.29 by Matthew Fuller
The param is clean_up, not clean-up.
161
    :param clean_up: if True, the backup.bzr directory is removed if the
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
162
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
163
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
164
    :return: attempted-control-dirs, succeeded-control-dirs, exceptions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
165
    """
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
166
    all_attempted = []
167
    all_succeeded = []
168
    all_exceptions = []
169
    for control_dir in control_dirs:
170
        attempted, succeeded, exceptions = _smart_upgrade_one(control_dir,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
171
            format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
172
        all_attempted.extend(attempted)
173
        all_succeeded.extend(succeeded)
174
        all_exceptions.extend(exceptions)
175
    return all_attempted, all_succeeded, all_exceptions
176
177
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
178
def _smart_upgrade_one(control_dir, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
179
    dry_run=False):
180
    """Convert a control directory to a new format intelligently.
181
4360.10.10 by Ian Clatworthy
minor clean-ups
182
    See smart_upgrade for parameter details.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
183
    """
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
184
    # If the URL is a shared repository, find the dependent branches
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
185
    dependents = None
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
186
    try:
187
        repo = control_dir.open_repository()
188
    except errors.NoRepositoryPresent:
189
        # A branch or checkout using a shared repository higher up
190
        pass
191
    else:
192
        # The URL is a repository. If it successfully upgrades,
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
193
        # then upgrade the dependent branches as well.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
194
        if repo.is_shared():
4360.10.17 by Ian Clatworthy
review feedback from abentley
195
            dependents = repo.find_branches(using=True)
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
196
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
197
    # Do the conversions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
198
    attempted = [control_dir]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
199
    succeeded, exceptions = _convert_items([control_dir], format, clean_up,
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
200
                                           dry_run)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
201
    if succeeded and dependents:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
202
        ui.ui_factory.note('Found %d dependent branches - upgrading ...'
203
                           % (len(dependents),))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
204
        # Convert dependent branches
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
205
        branch_cdirs = [b.bzrdir for b in dependents]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
206
        successes, problems = _convert_items(branch_cdirs, format, clean_up,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
207
            dry_run, label="branch")
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
208
        attempted.extend(branch_cdirs)
4360.10.3 by Ian Clatworthy
fix tests
209
        succeeded.extend(successes)
210
        exceptions.extend(problems)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
211
212
    # Return the result
213
    return attempted, succeeded, exceptions
214
4360.10.49 by Vincent Ladeuil
Make _get_object_and_label() private to upgrade.py, its inmplementation is both incomplete and returning info that are not used.
215
# FIXME: There are several problems below:
216
# - RemoteRepository doesn't support _unsupported (really ?)
217
# - raising AssertionError is rude and may not be necessary
218
# - no tests
219
# - the only caller uses only the label
220
def _get_object_and_label(control_dir):
221
    """Return the primary object and type label for a control directory.
222
223
    :return: object, label where
224
      object is a Branch, Repository or WorkingTree and
225
      label is one of:
226
        branch            - a branch
227
        repository        - a repository
228
        tree              - a lightweight checkout
229
    """
230
    try:
231
        try:
232
            br = control_dir.open_branch(unsupported=True,
233
                                         ignore_fallbacks=True)
234
        except NotImplementedError:
235
            # RemoteRepository doesn't support the unsupported parameter
236
            br = control_dir.open_branch(ignore_fallbacks=True)
237
    except errors.NotBranchError:
238
        pass
239
    else:
240
        return br, "branch"
241
    try:
242
        repo = control_dir.open_repository()
243
    except errors.NoRepositoryPresent:
244
        pass
245
    else:
246
        return repo, "repository"
247
    try:
248
        wt = control_dir.open_workingtree()
249
    except (errors.NoWorkingTree, errors.NotLocalUrl):
250
        pass
251
    else:
252
        return wt, "tree"
253
    raise AssertionError("unknown type of control directory %s", control_dir)
254
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
255
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
256
def _convert_items(items, format, clean_up, dry_run, label=None):
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
257
    """Convert a sequence of control directories to the given format.
258
 
259
    :param items: the control directories to upgrade
260
    :param format: the format to convert to or None for the best default
261
    :param clean-up: if True, the backup.bzr directory is removed if the
262
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
263
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
264
    :param label: the label for these items or None to calculate one
265
    :return: items successfully upgraded, exceptions
266
    """
267
    succeeded = []
268
    exceptions = []
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
269
    child_pb = ui.ui_factory.nested_progress_bar()
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
270
    child_pb.update('Upgrading bzrdirs', 0, len(items))
271
    for i, control_dir in enumerate(items):
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
272
        # Do the conversion
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
273
        location = control_dir.root_transport.base
4360.10.49 by Vincent Ladeuil
Make _get_object_and_label() private to upgrade.py, its inmplementation is both incomplete and returning info that are not used.
274
        bzr_object, bzr_label = _get_object_and_label(control_dir)
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
275
        type_label = label or bzr_label
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
276
        child_pb.update("Upgrading %s" % (type_label), i+1, len(items))
277
        ui.ui_factory.note('Upgrading %s %s ...' % (type_label, location,))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
278
        try:
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
279
            if not dry_run:
280
                cv = Convert(control_dir=control_dir, format=format)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
281
        except Exception, ex:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
282
            trace.warning('conversion error: %s' % ex)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
283
            exceptions.append(ex)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
284
            continue
285
286
        # Do any required post processing
287
        succeeded.append(control_dir)
288
        if clean_up:
289
            try:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
290
                ui.ui_factory.note('Removing backup ...')
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
291
                if not dry_run:
292
                    cv.clean_up()
293
            except Exception, ex:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
294
                trace.warning('failed to clean-up %s: %s' % (location, ex))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
295
                exceptions.append(ex)
296
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
297
    child_pb.finished()
298
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
299
    # Return the result
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
300
    return succeeded, exceptions