~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge sftp-leaks into catch-them-all

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
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(osutils.realpath(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.")
3529
3519
                                 'throughout the test suite.',
3530
3520
                            type=get_transport_type),
3531
3521
                     Option('benchmark',
3532
 
                            help='Run the benchmarks rather than selftests.'),
 
3522
                            help='Run the benchmarks rather than selftests.',
 
3523
                            hidden=True),
3533
3524
                     Option('lsprof-timed',
3534
3525
                            help='Generate lsprof output for benchmarked'
3535
3526
                                 ' sections of code.'),
3536
3527
                     Option('lsprof-tests',
3537
3528
                            help='Generate lsprof output for each test.'),
3538
 
                     Option('cache-dir', type=str,
3539
 
                            help='Cache intermediate benchmark output in this '
3540
 
                                 'directory.'),
3541
3529
                     Option('first',
3542
3530
                            help='Run all tests, but run specified tests first.',
3543
3531
                            short_name='f',
3577
3565
 
3578
3566
    def run(self, testspecs_list=None, verbose=False, one=False,
3579
3567
            transport=None, benchmark=None,
3580
 
            lsprof_timed=None, cache_dir=None,
 
3568
            lsprof_timed=None,
3581
3569
            first=False, list_only=False,
3582
3570
            randomize=None, exclude=None, strict=False,
3583
3571
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3584
3572
            parallel=None, lsprof_tests=False):
3585
 
        from bzrlib import (
3586
 
            benchmarks,
3587
 
            tests,
3588
 
            )
 
3573
        from bzrlib import tests
3589
3574
 
3590
3575
        # Make deprecation warnings visible, unless -Werror is set
3591
3576
        symbol_versioning.activate_deprecation_warnings(override=False)
3592
3577
 
3593
 
        if cache_dir is not None:
3594
 
            benchmarks.tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(
3595
 
                cache_dir)
3596
3578
        if testspecs_list is not None:
3597
3579
            pattern = '|'.join(testspecs_list)
3598
3580
        else:
3617
3599
            self.additional_selftest_args.setdefault(
3618
3600
                'suite_decorators', []).append(parallel)
3619
3601
        if benchmark:
3620
 
            test_suite_factory = benchmarks.test_suite
3621
 
            # Unless user explicitly asks for quiet, be verbose in benchmarks
3622
 
            verbose = not is_quiet()
3623
 
            # TODO: should possibly lock the history file...
3624
 
            benchfile = open(".perf_history", "at", buffering=1)
3625
 
            self.add_cleanup(benchfile.close)
3626
 
        else:
3627
 
            test_suite_factory = None
3628
 
            benchfile = None
 
3602
            raise errors.BzrCommandError(
 
3603
                "--benchmark is no longer supported from bzr 2.2; "
 
3604
                "use bzr-usertest instead")
 
3605
        test_suite_factory = None
3629
3606
        selftest_kwargs = {"verbose": verbose,
3630
3607
                          "pattern": pattern,
3631
3608
                          "stop_on_failure": one,
3633
3610
                          "test_suite_factory": test_suite_factory,
3634
3611
                          "lsprof_timed": lsprof_timed,
3635
3612
                          "lsprof_tests": lsprof_tests,
3636
 
                          "bench_history": benchfile,
3637
3613
                          "matching_tests_first": first,
3638
3614
                          "list_only": list_only,
3639
3615
                          "random_seed": randomize,
4093
4069
        from bzrlib.conflicts import restore
4094
4070
        if merge_type is None:
4095
4071
            merge_type = _mod_merge.Merge3Merger
4096
 
        tree, file_list = tree_files(file_list)
 
4072
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4097
4073
        self.add_cleanup(tree.lock_write().unlock)
4098
4074
        parents = tree.get_parent_ids()
4099
4075
        if len(parents) != 2:
4209
4185
 
4210
4186
    def run(self, revision=None, no_backup=False, file_list=None,
4211
4187
            forget_merges=None):
4212
 
        tree, file_list = tree_files(file_list)
 
4188
        tree, file_list = WorkingTree.open_containing_paths(file_list)
4213
4189
        self.add_cleanup(tree.lock_tree_write().unlock)
4214
4190
        if forget_merges:
4215
4191
            tree.set_parent_ids(tree.get_parent_ids()[:1])
5711
5687
            name=None,
5712
5688
            switch=None,
5713
5689
            ):
5714
 
        tree, file_list = tree_files(file_list, apply_view=False)
 
5690
        tree, file_list = WorkingTree.open_containing_paths(file_list,
 
5691
            apply_view=False)
5715
5692
        current_view, view_dict = tree.views.get_view_info()
5716
5693
        if name is None:
5717
5694
            name = current_view