~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
from bzrlib.lazy_import import lazy_import
23
23
lazy_import(globals(), """
24
24
import codecs
25
 
import errno
26
25
import sys
27
 
import tempfile
28
26
import time
29
27
 
30
28
import bzrlib
31
29
from bzrlib import (
32
 
    branch,
33
30
    bugtracker,
34
31
    bundle,
35
32
    bzrdir,
42
39
    merge as _mod_merge,
43
40
    merge_directive,
44
41
    osutils,
45
 
    registry,
46
 
    repository,
 
42
    reconfigure,
47
43
    revision as _mod_revision,
48
 
    revisionspec,
49
44
    symbol_versioning,
50
45
    transport,
51
46
    tree as _mod_tree,
61
56
 
62
57
from bzrlib.commands import Command, display_command
63
58
from bzrlib.option import ListOption, Option, RegistryOption, custom_help
64
 
from bzrlib.progress import DummyProgress, ProgressPhase
65
 
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
 
59
from bzrlib.trace import mutter, note, warning, is_quiet, info
66
60
 
67
61
 
68
62
def tree_files(file_list, default_branch=u'.'):
152
146
    To see ignored files use 'bzr ignored'.  For details on the
153
147
    changes to file texts, use 'bzr diff'.
154
148
    
155
 
    --short gives a status flags for each item, similar to the SVN's status
156
 
    command.
 
149
    Note that --short or -S gives status flags for each item, similar
 
150
    to Subversion's status command. To get output similar to svn -q,
 
151
    use bzr -SV.
157
152
 
158
153
    If no arguments are specified, the status of the entire working
159
154
    directory is shown.  Otherwise, only the status of the specified
168
163
    
169
164
    takes_args = ['file*']
170
165
    takes_options = ['show-ids', 'revision', 'change',
171
 
                     Option('short', help='Give short SVN-style status lines.'),
172
 
                     Option('versioned', help='Only show versioned files.')]
 
166
                     Option('short', help='Use short status indicators.',
 
167
                            short_name='S'),
 
168
                     Option('versioned', help='Only show versioned files.',
 
169
                            short_name='V')
 
170
                     ]
173
171
    aliases = ['st', 'stat']
174
172
 
175
173
    encoding_type = 'replace'
600
598
            tree_to = None
601
599
            branch_to = Branch.open_containing(directory)[0]
602
600
 
 
601
        possible_transports = []
603
602
        if location is not None:
604
603
            mergeable, location_transport = _get_mergeable_helper(location)
 
604
            possible_transports.append(location_transport)
605
605
 
606
606
        stored_loc = branch_to.get_parent()
607
607
        if location is None:
613
613
                        self.outf.encoding)
614
614
                self.outf.write("Using saved location: %s\n" % display_url)
615
615
                location = stored_loc
616
 
                location_transport = transport.get_transport(location)
 
616
                location_transport = transport.get_transport(
 
617
                    location, possible_transports=possible_transports)
617
618
 
618
619
        if mergeable is not None:
619
620
            if revision is not None:
639
640
        if verbose:
640
641
            old_rh = branch_to.revision_history()
641
642
        if tree_to is not None:
 
643
            change_reporter = delta._ChangeReporter(
 
644
                unversioned_filter=tree_to.is_ignored)
642
645
            result = tree_to.pull(branch_from, overwrite, revision_id,
643
 
                delta._ChangeReporter(unversioned_filter=tree_to.is_ignored))
 
646
                                  change_reporter,
 
647
                                  possible_transports=possible_transports)
644
648
        else:
645
649
            result = branch_to.pull(branch_from, overwrite, revision_id)
646
650
 
1012
1016
 
1013
1017
    def run(self, dir='.'):
1014
1018
        tree = WorkingTree.open_containing(dir)[0]
1015
 
        master = tree.branch.get_master_branch()
 
1019
        possible_transports = []
 
1020
        master = tree.branch.get_master_branch(
 
1021
            possible_transports=possible_transports)
1016
1022
        if master is not None:
1017
1023
            tree.lock_write()
1018
1024
        else:
1028
1034
                    revno = tree.branch.revision_id_to_revno(last_rev)
1029
1035
                    note("Tree is up to date at revision %d." % (revno,))
1030
1036
                    return 0
1031
 
            conflicts = tree.update(delta._ChangeReporter(
1032
 
                                        unversioned_filter=tree.is_ignored))
 
1037
            conflicts = tree.update(
 
1038
                delta._ChangeReporter(unversioned_filter=tree.is_ignored),
 
1039
                possible_transports=possible_transports)
1033
1040
            revno = tree.branch.revision_id_to_revno(
1034
1041
                _mod_revision.ensure_null(tree.last_revision()))
1035
1042
            note('Updated to revision %d.' % (revno,))
1098
1105
        tree, file_list = tree_files(file_list)
1099
1106
 
1100
1107
        if file_list is not None:
1101
 
            file_list = [f for f in file_list if f != '']
 
1108
            file_list = [f for f in file_list]
1102
1109
        elif not new:
1103
1110
            raise errors.BzrCommandError('Specify one or more files to'
1104
1111
            ' remove, or use --new.')
1422
1429
               help='Pass these options to the external diff program.'),
1423
1430
        Option('prefix', type=str,
1424
1431
               short_name='p',
1425
 
               help='Set prefixes to added to old and new filenames, as '
 
1432
               help='Set prefixes added to old and new filenames, as '
1426
1433
                    'two values separated by a colon. (eg "old/:new/").'),
1427
1434
        'revision',
1428
1435
        'change',
2246
2253
    def run(self, message=None, file=None, verbose=False, selected_list=None,
2247
2254
            unchanged=False, strict=False, local=False, fixes=None,
2248
2255
            author=None, show_diff=False):
2249
 
        from bzrlib.commit import (
2250
 
            NullCommitReporter,
2251
 
            ReportCommitToLog
2252
 
        )
2253
2256
        from bzrlib.errors import (
2254
2257
            PointlessCommit,
2255
2258
            ConflictsInTree,
2275
2278
            # selected-file merge commit is not done yet
2276
2279
            selected_list = []
2277
2280
 
 
2281
        if fixes is None:
 
2282
            fixes = []
2278
2283
        bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2279
2284
        if bug_property:
2280
2285
            properties['bugs'] = bug_property
2303
2308
                raise errors.BzrCommandError("empty commit message specified")
2304
2309
            return my_message
2305
2310
 
2306
 
        if verbose or not is_quiet():
2307
 
            reporter = ReportCommitToLog()
2308
 
        else:
2309
 
            reporter = NullCommitReporter()
2310
 
 
2311
2311
        try:
2312
2312
            tree.commit(message_callback=get_message,
2313
2313
                        specific_files=selected_list,
2314
2314
                        allow_pointless=unchanged, strict=strict, local=local,
2315
 
                        reporter=reporter, revprops=properties,
 
2315
                        reporter=None, verbose=verbose, revprops=properties,
2316
2316
                        author=author)
2317
2317
        except PointlessCommit:
2318
2318
            # FIXME: This should really happen before the file is read in;
2548
2548
                     ]
2549
2549
    encoding_type = 'replace'
2550
2550
 
2551
 
    def run(self, testspecs_list=None, verbose=None, one=False,
 
2551
    def run(self, testspecs_list=None, verbose=False, one=False,
2552
2552
            transport=None, benchmark=None,
2553
2553
            lsprof_timed=None, cache_dir=None,
2554
2554
            first=False, list_only=False,
2557
2557
        from bzrlib.tests import selftest
2558
2558
        import bzrlib.benchmarks as benchmarks
2559
2559
        from bzrlib.benchmarks import tree_creator
2560
 
        from bzrlib.version import show_version
2561
2560
 
2562
2561
        if cache_dir is not None:
2563
2562
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2575
2574
            pattern = ".*"
2576
2575
        if benchmark:
2577
2576
            test_suite_factory = benchmarks.test_suite
2578
 
            if verbose is None:
2579
 
                verbose = True
 
2577
            # Unless user explicitly asks for quiet, be verbose in benchmarks
 
2578
            verbose = not is_quiet()
2580
2579
            # TODO: should possibly lock the history file...
2581
2580
            benchfile = open(".perf_history", "at", buffering=1)
2582
2581
        else:
2583
2582
            test_suite_factory = None
2584
 
            if verbose is None:
2585
 
                verbose = False
2586
2583
            benchfile = None
2587
2584
        try:
2588
2585
            result = selftest(verbose=verbose,
2611
2608
class cmd_version(Command):
2612
2609
    """Show version of bzr."""
2613
2610
 
 
2611
    encoding_type = 'replace'
 
2612
 
2614
2613
    @display_command
2615
2614
    def run(self):
2616
2615
        from bzrlib.version import show_version
2617
 
        show_version()
 
2616
        show_version(to_file=self.outf)
2618
2617
 
2619
2618
 
2620
2619
class cmd_rocks(Command):
2636
2635
    
2637
2636
    @display_command
2638
2637
    def run(self, branch, other):
2639
 
        from bzrlib.revision import ensure_null, MultipleRevisionSources
 
2638
        from bzrlib.revision import ensure_null
2640
2639
        
2641
2640
        branch1 = Branch.open_containing(branch)[0]
2642
2641
        branch2 = Branch.open_containing(other)[0]
2699
2698
    _see_also = ['update', 'remerge', 'status-flags']
2700
2699
    takes_args = ['branch?']
2701
2700
    takes_options = [
 
2701
        'change',
2702
2702
        'revision',
2703
2703
        Option('force',
2704
2704
               help='Merge even if the destination tree has uncommitted changes.'),
2726
2726
            uncommitted=False, pull=False,
2727
2727
            directory=None,
2728
2728
            ):
2729
 
        from bzrlib.tag import _merge_tags_if_possible
2730
2729
        # This is actually a branch (or merge-directive) *location*.
2731
2730
        location = branch
2732
2731
        del branch
2787
2786
                return 0
2788
2787
            if pull:
2789
2788
                if merger.interesting_files is not None:
2790
 
                    raise BzrCommandError('Cannot pull individual files')
 
2789
                    raise errors.BzrCommandError('Cannot pull individual files')
2791
2790
                if (merger.base_rev_id == tree.last_revision()):
2792
2791
                    result = tree.pull(merger.other_branch, False,
2793
2792
                                       merger.other_rev_id)
3046
3045
 
3047
3046
    _see_also = ['cat', 'export']
3048
3047
    takes_options = [
3049
 
            'revision',
3050
 
            Option('no-backup', "Do not save backups of reverted files."),
3051
 
            ]
 
3048
        'revision',
 
3049
        Option('no-backup', "Do not save backups of reverted files."),
 
3050
        Option('forget-merges',
 
3051
               'Remove pending merge marker, without changing any files.'),
 
3052
        ]
3052
3053
    takes_args = ['file*']
3053
3054
 
3054
 
    def run(self, revision=None, no_backup=False, file_list=None):
3055
 
        if file_list is not None:
3056
 
            if len(file_list) == 0:
3057
 
                raise errors.BzrCommandError("No files specified")
 
3055
    def run(self, revision=None, no_backup=False, file_list=None,
 
3056
            forget_merges=None):
 
3057
        tree, file_list = tree_files(file_list)
 
3058
        if forget_merges:
 
3059
            tree.set_parent_ids(tree.get_parent_ids()[:1])
3058
3060
        else:
3059
 
            file_list = []
3060
 
        
3061
 
        tree, file_list = tree_files(file_list)
 
3061
            self._revert_tree_to_revision(tree, revision, file_list, no_backup)
 
3062
 
 
3063
    @staticmethod
 
3064
    def _revert_tree_to_revision(tree, revision, file_list, no_backup):
3062
3065
        if revision is None:
3063
 
            # FIXME should be tree.last_revision
3064
3066
            rev_id = tree.last_revision()
3065
3067
        elif len(revision) != 1:
3066
3068
            raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
3068
3070
            rev_id = revision[0].in_history(tree.branch).rev_id
3069
3071
        pb = ui.ui_factory.nested_progress_bar()
3070
3072
        try:
3071
 
            tree.revert(file_list, 
 
3073
            tree.revert(file_list,
3072
3074
                        tree.branch.repository.revision_tree(rev_id),
3073
3075
                        not no_backup, pb, report_changes=True)
3074
3076
        finally:
3160
3162
            theirs_only=False, log_format=None, long=False, short=False, line=False, 
3161
3163
            show_ids=False, verbose=False, this=False, other=False):
3162
3164
        from bzrlib.missing import find_unmerged, iter_log_revisions
3163
 
        from bzrlib.log import log_formatter
3164
3165
 
3165
3166
        if this:
3166
3167
          mine_only = this
3475
3476
            dry_run=False, verbose=False,
3476
3477
            revision=None, force=False):
3477
3478
        from bzrlib.log import log_formatter, show_log
3478
 
        import sys
3479
3479
        from bzrlib.uncommit import uncommit
3480
3480
 
3481
3481
        if location is None:
3847
3847
    the preferred client can't be found (or used), your editor will be used.
3848
3848
    
3849
3849
    To use a specific mail program, set the mail_client configuration option.
3850
 
    (For Thunderbird 1.5, this works around some bugs.)  Supported values are
3851
 
    "thunderbird", "evolution", "editor", "xdg-email", "mapi", "kmail" and
3852
 
    "default".
 
3850
    (For Thunderbird 1.5, this works around some bugs.)  Supported values for
 
3851
    specific clients are "evolution", "kmail", "mutt", and "thunderbird";
 
3852
    generic options are "default", "editor", "mapi", and "xdg-email".
3853
3853
 
3854
3854
    If mail is being sent, a to address is required.  This can be supplied
3855
3855
    either on the commandline, or by setting the submit_to configuration
3864
3864
 
3865
3865
    encoding_type = 'exact'
3866
3866
 
3867
 
    _see_also = ['merge', 'doc/configuration.txt']
 
3867
    _see_also = ['merge']
3868
3868
 
3869
3869
    takes_args = ['submit_branch?', 'public_branch?']
3870
3870
 
3901
3901
 
3902
3902
    def _run(self, submit_branch, revision, public_branch, remember, format,
3903
3903
             no_bundle, no_patch, output, from_, mail_to, message):
3904
 
        from bzrlib.revision import ensure_null, NULL_REVISION
 
3904
        from bzrlib.revision import NULL_REVISION
3905
3905
        if output is None:
3906
3906
            outfile = StringIO()
3907
3907
        elif output == '-':
4153
4153
            self.outf.write('%-20s %s\n' % (tag_name, target))
4154
4154
 
4155
4155
 
 
4156
class cmd_reconfigure(Command):
 
4157
    """Reconfigure the type of a bzr directory.
 
4158
 
 
4159
    A target configuration must be specified.
 
4160
 
 
4161
    For checkouts, the bind-to location will be auto-detected if not specified.
 
4162
    The order of preference is
 
4163
    1. For a lightweight checkout, the current bound location.
 
4164
    2. For branches that used to be checkouts, the previously-bound location.
 
4165
    3. The push location.
 
4166
    4. The parent location.
 
4167
    If none of these is available, --bind-to must be specified.
 
4168
    """
 
4169
 
 
4170
    takes_args = ['location?']
 
4171
    takes_options = [RegistryOption.from_kwargs('target_type',
 
4172
                     title='Target type',
 
4173
                     help='The type to reconfigure the directory to.',
 
4174
                     value_switches=True, enum_switch=False,
 
4175
                     branch='Reconfigure to a branch.',
 
4176
                     tree='Reconfigure to a tree.',
 
4177
                     checkout='Reconfigure to a checkout.'),
 
4178
                     Option('bind-to', help='Branch to bind checkout to.',
 
4179
                            type=str),
 
4180
                     Option('force',
 
4181
                        help='Perform reconfiguration even if local changes'
 
4182
                        ' will be lost.')
 
4183
                     ]
 
4184
 
 
4185
    def run(self, location=None, target_type=None, bind_to=None, force=False):
 
4186
        directory = bzrdir.BzrDir.open(location)
 
4187
        if target_type is None:
 
4188
            raise errors.BzrCommandError('No target configuration specified')
 
4189
        elif target_type == 'branch':
 
4190
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
 
4191
        elif target_type == 'tree':
 
4192
            reconfiguration = reconfigure.Reconfigure.to_tree(directory)
 
4193
        elif target_type == 'checkout':
 
4194
            reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
 
4195
                                                                  bind_to)
 
4196
        reconfiguration.apply(force)
 
4197
 
 
4198
 
4156
4199
def _create_prefix(cur_transport):
4157
4200
    needed = [cur_transport]
4158
4201
    # Recurse upwards until we can create a directory successfully