~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 08:02:42 UTC
  • mfrom: (5390.3.3 faster-revert-593560)
  • Revision ID: pqm@pqm.ubuntu.com-20100901080242-esg62ody4frwmy66
(spiv) Avoid repeatedly calling self.target.all_file_ids() in
 InterTree.iter_changes. (Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
from bzrlib.lazy_import import lazy_import
22
22
lazy_import(globals(), """
23
 
import codecs
24
23
import cStringIO
25
24
import sys
26
25
import time
33
32
    bzrdir,
34
33
    directory_service,
35
34
    delta,
36
 
    config,
 
35
    config as _mod_config,
37
36
    errors,
38
37
    globbing,
39
38
    hooks,
75
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
76
75
 
77
76
 
 
77
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
78
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
79
79
    apply_view=True):
80
 
    try:
81
 
        return internal_tree_files(file_list, default_branch, canonicalize,
82
 
            apply_view)
83
 
    except errors.FileInWrongBranch, e:
84
 
        raise errors.BzrCommandError("%s is not in the same branch as %s" %
85
 
                                     (e.path, file_list[0]))
 
80
    return internal_tree_files(file_list, default_branch, canonicalize,
 
81
        apply_view)
86
82
 
87
83
 
88
84
def tree_files_for_add(file_list):
152
148
 
153
149
# XXX: Bad function name; should possibly also be a class method of
154
150
# WorkingTree rather than a function.
 
151
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
155
152
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
156
153
    apply_view=True):
157
154
    """Convert command-line paths to a WorkingTree and relative paths.
158
155
 
 
156
    Deprecated: use WorkingTree.open_containing_paths instead.
 
157
 
159
158
    This is typically used for command-line processors that take one or
160
159
    more filenames, and infer the workingtree that contains them.
161
160
 
171
170
 
172
171
    :return: workingtree, [relative_paths]
173
172
    """
174
 
    if file_list is None or len(file_list) == 0:
175
 
        tree = WorkingTree.open_containing(default_branch)[0]
176
 
        if tree.supports_views() and apply_view:
177
 
            view_files = tree.views.lookup_view()
178
 
            if view_files:
179
 
                file_list = view_files
180
 
                view_str = views.view_display_str(view_files)
181
 
                note("Ignoring files outside view. View is %s" % view_str)
182
 
        return tree, file_list
183
 
    tree = WorkingTree.open_containing(file_list[0])[0]
184
 
    return tree, safe_relpath_files(tree, file_list, canonicalize,
185
 
        apply_view=apply_view)
186
 
 
187
 
 
188
 
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
189
 
    """Convert file_list into a list of relpaths in tree.
190
 
 
191
 
    :param tree: A tree to operate on.
192
 
    :param file_list: A list of user provided paths or None.
193
 
    :param apply_view: if True and a view is set, apply it or check that
194
 
        specified files are within it
195
 
    :return: A list of relative paths.
196
 
    :raises errors.PathNotChild: When a provided path is in a different tree
197
 
        than tree.
198
 
    """
199
 
    if file_list is None:
200
 
        return None
201
 
    if tree.supports_views() and apply_view:
202
 
        view_files = tree.views.lookup_view()
203
 
    else:
204
 
        view_files = []
205
 
    new_list = []
206
 
    # tree.relpath exists as a "thunk" to osutils, but canonical_relpath
207
 
    # doesn't - fix that up here before we enter the loop.
208
 
    if canonicalize:
209
 
        fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
210
 
    else:
211
 
        fixer = tree.relpath
212
 
    for filename in file_list:
213
 
        try:
214
 
            relpath = fixer(osutils.dereference_path(filename))
215
 
            if  view_files and not osutils.is_inside_any(view_files, relpath):
216
 
                raise errors.FileOutsideView(filename, view_files)
217
 
            new_list.append(relpath)
218
 
        except errors.PathNotChild:
219
 
            raise errors.FileInWrongBranch(tree.branch, filename)
220
 
    return new_list
 
173
    return WorkingTree.open_containing_paths(
 
174
        file_list, default_directory='.',
 
175
        canonicalize=True,
 
176
        apply_view=True)
221
177
 
222
178
 
223
179
def _get_view_info_for_change_reporter(tree):
323
279
            raise errors.BzrCommandError('bzr status --revision takes exactly'
324
280
                                         ' one or two revision specifiers')
325
281
 
326
 
        tree, relfile_list = tree_files(file_list)
 
282
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
327
283
        # Avoid asking for specific files when that is not needed.
328
284
        if relfile_list == ['']:
329
285
            relfile_list = None
761
717
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
762
718
 
763
719
        revision = _get_one_revision('inventory', revision)
764
 
        work_tree, file_list = tree_files(file_list)
 
720
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
765
721
        self.add_cleanup(work_tree.lock_read().unlock)
766
722
        if revision is not None:
767
723
            tree = revision.as_tree(work_tree.branch)
832
788
            names_list = []
833
789
        if len(names_list) < 2:
834
790
            raise errors.BzrCommandError("missing file argument")
835
 
        tree, rel_names = tree_files(names_list, canonicalize=False)
 
791
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
836
792
        self.add_cleanup(tree.lock_tree_write().unlock)
837
793
        self._run(tree, names_list, rel_names, after)
838
794
 
843
799
        if after:
844
800
            raise errors.BzrCommandError('--after cannot be specified with'
845
801
                                         ' --auto.')
846
 
        work_tree, file_list = tree_files(names_list, default_branch='.')
 
802
        work_tree, file_list = WorkingTree.open_containing_paths(
 
803
            names_list, default_directory='.')
847
804
        self.add_cleanup(work_tree.lock_tree_write().unlock)
848
805
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
849
806
 
1177
1134
 
1178
1135
    _see_also = ['checkout']
1179
1136
    takes_args = ['from_location', 'to_location?']
1180
 
    takes_options = ['revision', Option('hardlink',
1181
 
        help='Hard-link working tree files where possible.'),
 
1137
    takes_options = ['revision',
 
1138
        Option('hardlink', help='Hard-link working tree files where possible.'),
 
1139
        Option('files-from', type=str,
 
1140
               help="Get file contents from this tree."),
1182
1141
        Option('no-tree',
1183
1142
            help="Create a branch without a working-tree."),
1184
1143
        Option('switch',
1202
1161
 
1203
1162
    def run(self, from_location, to_location=None, revision=None,
1204
1163
            hardlink=False, stacked=False, standalone=False, no_tree=False,
1205
 
            use_existing_dir=False, switch=False, bind=False):
 
1164
            use_existing_dir=False, switch=False, bind=False,
 
1165
            files_from=None):
1206
1166
        from bzrlib import switch as _mod_switch
1207
1167
        from bzrlib.tag import _merge_tags_if_possible
1208
1168
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1209
1169
            from_location)
 
1170
        if not (hardlink or files_from):
 
1171
            # accelerator_tree is usually slower because you have to read N
 
1172
            # files (no readahead, lots of seeks, etc), but allow the user to
 
1173
            # explicitly request it
 
1174
            accelerator_tree = None
 
1175
        if files_from is not None and files_from != from_location:
 
1176
            accelerator_tree = WorkingTree.open(files_from)
1210
1177
        revision = _get_one_revision('branch', revision)
1211
1178
        self.add_cleanup(br_from.lock_read().unlock)
1212
1179
        if revision is not None:
1319
1286
            to_location = branch_location
1320
1287
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1321
1288
            branch_location)
 
1289
        if not (hardlink or files_from):
 
1290
            # accelerator_tree is usually slower because you have to read N
 
1291
            # files (no readahead, lots of seeks, etc), but allow the user to
 
1292
            # explicitly request it
 
1293
            accelerator_tree = None
1322
1294
        revision = _get_one_revision('checkout', revision)
1323
 
        if files_from is not None:
 
1295
        if files_from is not None and files_from != branch_location:
1324
1296
            accelerator_tree = WorkingTree.open(files_from)
1325
1297
        if revision is not None:
1326
1298
            revision_id = revision.as_revision_id(source)
1505
1477
class cmd_remove(Command):
1506
1478
    __doc__ = """Remove files or directories.
1507
1479
 
1508
 
    This makes bzr stop tracking changes to the specified files. bzr will delete
1509
 
    them if they can easily be recovered using revert. If no options or
1510
 
    parameters are given bzr will scan for files that are being tracked by bzr
1511
 
    but missing in your tree and stop tracking them for you.
 
1480
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
 
1481
    delete them if they can easily be recovered using revert otherwise they
 
1482
    will be backed up (adding an extention of the form .~#~). If no options or
 
1483
    parameters are given Bazaar will scan for files that are being tracked by
 
1484
    Bazaar but missing in your tree and stop tracking them for you.
1512
1485
    """
1513
1486
    takes_args = ['file*']
1514
1487
    takes_options = ['verbose',
1516
1489
        RegistryOption.from_kwargs('file-deletion-strategy',
1517
1490
            'The file deletion mode to be used.',
1518
1491
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1519
 
            safe='Only delete files if they can be'
1520
 
                 ' safely recovered (default).',
 
1492
            safe='Backup changed files (default).',
1521
1493
            keep='Delete from bzr but leave the working copy.',
1522
1494
            force='Delete all the specified files, even if they can not be '
1523
1495
                'recovered and even if they are non-empty directories.')]
1526
1498
 
1527
1499
    def run(self, file_list, verbose=False, new=False,
1528
1500
        file_deletion_strategy='safe'):
1529
 
        tree, file_list = tree_files(file_list)
 
1501
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1530
1502
 
1531
1503
        if file_list is not None:
1532
1504
            file_list = [f for f in file_list]
1620
1592
 
1621
1593
    _see_also = ['check']
1622
1594
    takes_args = ['branch?']
 
1595
    takes_options = [
 
1596
        Option('canonicalize-chks',
 
1597
               help='Make sure CHKs are in canonical form (repairs '
 
1598
                    'bug 522637).',
 
1599
               hidden=True),
 
1600
        ]
1623
1601
 
1624
 
    def run(self, branch="."):
 
1602
    def run(self, branch=".", canonicalize_chks=False):
1625
1603
        from bzrlib.reconcile import reconcile
1626
1604
        dir = bzrdir.BzrDir.open(branch)
1627
 
        reconcile(dir)
 
1605
        reconcile(dir, canonicalize_chks=canonicalize_chks)
1628
1606
 
1629
1607
 
1630
1608
class cmd_revision_history(Command):
1906
1884
        Same as 'bzr diff' but prefix paths with old/ and new/::
1907
1885
 
1908
1886
            bzr diff --prefix old/:new/
 
1887
            
 
1888
        Show the differences using a custom diff program with options::
 
1889
        
 
1890
            bzr diff --using /usr/bin/diff --diff-options -wu
1909
1891
    """
1910
1892
    _see_also = ['status']
1911
1893
    takes_args = ['file*']
2712
2694
                "NAME_PATTERN or --default-rules.")
2713
2695
        name_pattern_list = [globbing.normalize_pattern(p)
2714
2696
                             for p in name_pattern_list]
 
2697
        bad_patterns = ''
 
2698
        for p in name_pattern_list:
 
2699
            if not globbing.Globster.is_pattern_valid(p):
 
2700
                bad_patterns += ('\n  %s' % p)
 
2701
        if bad_patterns:
 
2702
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
 
2703
            ui.ui_factory.show_error(msg)
 
2704
            raise errors.InvalidPattern('')
2715
2705
        for name_pattern in name_pattern_list:
2716
2706
            if (name_pattern[0] == '/' or
2717
2707
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
3109
3099
 
3110
3100
        properties = {}
3111
3101
 
3112
 
        tree, selected_list = tree_files(selected_list)
 
3102
        tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3113
3103
        if selected_list == ['']:
3114
3104
            # workaround - commit of root of tree should be exactly the same
3115
3105
            # as just default commit in that tree, and succeed even though
3150
3140
        def get_message(commit_obj):
3151
3141
            """Callback to get commit message"""
3152
3142
            if file:
3153
 
                f = codecs.open(file, 'rt', osutils.get_user_encoding())
 
3143
                f = open(file)
3154
3144
                try:
3155
 
                    my_message = f.read()
 
3145
                    my_message = f.read().decode(osutils.get_user_encoding())
3156
3146
                finally:
3157
3147
                    f.close()
3158
3148
            elif message is not None:
3189
3179
                        reporter=None, verbose=verbose, revprops=properties,
3190
3180
                        authors=author, timestamp=commit_stamp,
3191
3181
                        timezone=offset,
3192
 
                        exclude=safe_relpath_files(tree, exclude))
 
3182
                        exclude=tree.safe_relpath_files(exclude))
3193
3183
        except PointlessCommit:
3194
3184
            raise errors.BzrCommandError("No changes to commit."
3195
3185
                              " Use --unchanged to commit anyhow.")
3332
3322
                try:
3333
3323
                    c = Branch.open_containing(u'.')[0].get_config()
3334
3324
                except errors.NotBranchError:
3335
 
                    c = config.GlobalConfig()
 
3325
                    c = _mod_config.GlobalConfig()
3336
3326
            else:
3337
3327
                c = Branch.open(directory).get_config()
3338
3328
            if email:
3343
3333
 
3344
3334
        # display a warning if an email address isn't included in the given name.
3345
3335
        try:
3346
 
            config.extract_email_address(name)
 
3336
            _mod_config.extract_email_address(name)
3347
3337
        except errors.NoEmailInUsername, e:
3348
3338
            warning('"%s" does not seem to contain an email address.  '
3349
3339
                    'This is allowed, but not recommended.', name)
3355
3345
            else:
3356
3346
                c = Branch.open(directory).get_config()
3357
3347
        else:
3358
 
            c = config.GlobalConfig()
 
3348
            c = _mod_config.GlobalConfig()
3359
3349
        c.set_user_option('email', name)
3360
3350
 
3361
3351
 
3428
3418
                'bzr alias --remove expects an alias to remove.')
3429
3419
        # If alias is not found, print something like:
3430
3420
        # unalias: foo: not found
3431
 
        c = config.GlobalConfig()
 
3421
        c = _mod_config.GlobalConfig()
3432
3422
        c.unset_alias(alias_name)
3433
3423
 
3434
3424
    @display_command
3435
3425
    def print_aliases(self):
3436
3426
        """Print out the defined aliases in a similar format to bash."""
3437
 
        aliases = config.GlobalConfig().get_aliases()
 
3427
        aliases = _mod_config.GlobalConfig().get_aliases()
3438
3428
        for key, value in sorted(aliases.iteritems()):
3439
3429
            self.outf.write('bzr alias %s="%s"\n' % (key, value))
3440
3430
 
3450
3440
 
3451
3441
    def set_alias(self, alias_name, alias_command):
3452
3442
        """Save the alias in the global config."""
3453
 
        c = config.GlobalConfig()
 
3443
        c = _mod_config.GlobalConfig()
3454
3444
        c.set_alias(alias_name, alias_command)
3455
3445
 
3456
3446
 
3580
3570
            randomize=None, exclude=None, strict=False,
3581
3571
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3582
3572
            parallel=None, lsprof_tests=False):
3583
 
        from bzrlib.tests import selftest
3584
 
 
3585
 
        # Make deprecation warnings visible, unless -Werror is set
3586
 
        symbol_versioning.activate_deprecation_warnings(override=False)
 
3573
        from bzrlib import tests
3587
3574
 
3588
3575
        if testspecs_list is not None:
3589
3576
            pattern = '|'.join(testspecs_list)
3630
3617
                          "starting_with": starting_with
3631
3618
                          }
3632
3619
        selftest_kwargs.update(self.additional_selftest_args)
3633
 
        result = selftest(**selftest_kwargs)
 
3620
 
 
3621
        # Make deprecation warnings visible, unless -Werror is set
 
3622
        cleanup = symbol_versioning.activate_deprecation_warnings(
 
3623
            override=False)
 
3624
        try:
 
3625
            result = tests.selftest(**selftest_kwargs)
 
3626
        finally:
 
3627
            cleanup()
3634
3628
        return int(not result)
3635
3629
 
3636
3630
 
4079
4073
        from bzrlib.conflicts import restore
4080
4074
        if merge_type is None:
4081
4075
            merge_type = _mod_merge.Merge3Merger
4082
 
        tree, file_list = tree_files(file_list)
 
4076
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4083
4077
        self.add_cleanup(tree.lock_write().unlock)
4084
4078
        parents = tree.get_parent_ids()
4085
4079
        if len(parents) != 2:
4195
4189
 
4196
4190
    def run(self, revision=None, no_backup=False, file_list=None,
4197
4191
            forget_merges=None):
4198
 
        tree, file_list = tree_files(file_list)
 
4192
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4199
4193
        self.add_cleanup(tree.lock_tree_write().unlock)
4200
4194
        if forget_merges:
4201
4195
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4817
4811
 
4818
4812
 
4819
4813
class cmd_break_lock(Command):
4820
 
    __doc__ = """Break a dead lock on a repository, branch or working directory.
 
4814
    __doc__ = """Break a dead lock.
 
4815
 
 
4816
    This command breaks a lock on a repository, branch, working directory or
 
4817
    config file.
4821
4818
 
4822
4819
    CAUTION: Locks should only be broken when you are sure that the process
4823
4820
    holding the lock has been stopped.
4828
4825
    :Examples:
4829
4826
        bzr break-lock
4830
4827
        bzr break-lock bzr+ssh://example.com/bzr/foo
 
4828
        bzr break-lock --conf ~/.bazaar
4831
4829
    """
 
4830
 
4832
4831
    takes_args = ['location?']
 
4832
    takes_options = [
 
4833
        Option('config',
 
4834
               help='LOCATION is the directory where the config lock is.'),
 
4835
        ]
4833
4836
 
4834
 
    def run(self, location=None, show=False):
 
4837
    def run(self, location=None, config=False):
4835
4838
        if location is None:
4836
4839
            location = u'.'
4837
 
        control, relpath = bzrdir.BzrDir.open_containing(location)
4838
 
        try:
4839
 
            control.break_lock()
4840
 
        except NotImplementedError:
4841
 
            pass
 
4840
        if config:
 
4841
            conf = _mod_config.LockableConfig(file_name=location)
 
4842
            conf.break_lock()
 
4843
        else:
 
4844
            control, relpath = bzrdir.BzrDir.open_containing(location)
 
4845
            try:
 
4846
                control.break_lock()
 
4847
            except NotImplementedError:
 
4848
                pass
4842
4849
 
4843
4850
 
4844
4851
class cmd_wait_until_signalled(Command):
5697
5704
            name=None,
5698
5705
            switch=None,
5699
5706
            ):
5700
 
        tree, file_list = tree_files(file_list, apply_view=False)
 
5707
        tree, file_list = WorkingTree.open_containing_paths(file_list,
 
5708
            apply_view=False)
5701
5709
        current_view, view_dict = tree.views.get_view_info()
5702
5710
        if name is None:
5703
5711
            name = current_view