/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Robert Collins
  • Date: 2010-06-25 20:34:05 UTC
  • mto: This revision was merged to the branch mainline in revision 5324.
  • Revision ID: robertc@robertcollins.net-20100625203405-c74lxd3enklhaqf9
``bzrlib.osutils.get_terminal_encoding`` will now only mutter its
selection when explicitly requested; this avoids many duplicate calls
being logged when helpers, wrappers and older code that manually calls
it are executed it is now logged deliberately by the ui setup code.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
232
232
    return view_info
233
233
 
234
234
 
 
235
def _open_directory_or_containing_tree_or_branch(filename, directory):
 
236
    """Open the tree or branch containing the specified file, unless
 
237
    the --directory option is used to specify a different branch."""
 
238
    if directory is not None:
 
239
        return (None, Branch.open(directory), filename)
 
240
    return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
241
 
 
242
 
235
243
# TODO: Make sure no commands unconditionally use the working directory as a
236
244
# branch.  If a filename argument is used, the first of them should be used to
237
245
# specify the branch.  (Perhaps this can be factored out into some kind of
340
348
 
341
349
    hidden = True
342
350
    takes_args = ['revision_id?']
343
 
    takes_options = ['revision']
 
351
    takes_options = ['directory', 'revision']
344
352
    # cat-revision is more for frontends so should be exact
345
353
    encoding = 'strict'
346
354
 
353
361
        self.outf.write(revtext.decode('utf-8'))
354
362
 
355
363
    @display_command
356
 
    def run(self, revision_id=None, revision=None):
 
364
    def run(self, revision_id=None, revision=None, directory=u'.'):
357
365
        if revision_id is not None and revision is not None:
358
366
            raise errors.BzrCommandError('You can only supply one of'
359
367
                                         ' revision_id or --revision')
360
368
        if revision_id is None and revision is None:
361
369
            raise errors.BzrCommandError('You must supply either'
362
370
                                         ' --revision or a revision_id')
363
 
        b = WorkingTree.open_containing(u'.')[0].branch
 
371
        b = WorkingTree.open_containing(directory)[0].branch
364
372
 
365
373
        revisions = b.repository.revisions
366
374
        if revisions is None:
483
491
    takes_options = [
484
492
        Option('force',
485
493
               help='Remove the working tree even if it has '
486
 
                    'uncommitted changes.'),
 
494
                    'uncommitted or shelved changes.'),
487
495
        ]
488
496
 
489
497
    def run(self, location_list, force=False):
503
511
            if not force:
504
512
                if (working.has_changes()):
505
513
                    raise errors.UncommittedChanges(working)
 
514
                if working.get_shelf_manager().last_shelf() is not None:
 
515
                    raise errors.ShelvedChanges(working)
506
516
 
507
517
            if working.user_url != working.branch.user_url:
508
518
                raise errors.BzrCommandError("You cannot remove the working tree"
528
538
        if tree:
529
539
            try:
530
540
                wt = WorkingTree.open_containing(location)[0]
531
 
                wt.lock_read()
 
541
                self.add_cleanup(wt.lock_read().unlock)
532
542
            except (errors.NoWorkingTree, errors.NotLocalUrl):
533
543
                raise errors.NoWorkingTree(location)
534
 
            self.add_cleanup(wt.unlock)
535
544
            revid = wt.last_revision()
536
545
            try:
537
546
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
540
549
            revno = ".".join(str(n) for n in revno_t)
541
550
        else:
542
551
            b = Branch.open_containing(location)[0]
543
 
            b.lock_read()
544
 
            self.add_cleanup(b.unlock)
 
552
            self.add_cleanup(b.lock_read().unlock)
545
553
            revno = b.revno()
546
554
        self.cleanup_now()
547
555
        self.outf.write(str(revno) + '\n')
554
562
    takes_args = ['revision_info*']
555
563
    takes_options = [
556
564
        'revision',
557
 
        Option('directory',
 
565
        custom_help('directory',
558
566
            help='Branch to examine, '
559
 
                 'rather than the one containing the working directory.',
560
 
            short_name='d',
561
 
            type=unicode,
562
 
            ),
 
567
                 'rather than the one containing the working directory.'),
563
568
        Option('tree', help='Show revno of working tree'),
564
569
        ]
565
570
 
570
575
        try:
571
576
            wt = WorkingTree.open_containing(directory)[0]
572
577
            b = wt.branch
573
 
            wt.lock_read()
574
 
            self.add_cleanup(wt.unlock)
 
578
            self.add_cleanup(wt.lock_read().unlock)
575
579
        except (errors.NoWorkingTree, errors.NotLocalUrl):
576
580
            wt = None
577
581
            b = Branch.open_containing(directory)[0]
578
 
            b.lock_read()
579
 
            self.add_cleanup(b.unlock)
 
582
            self.add_cleanup(b.lock_read().unlock)
580
583
        revision_ids = []
581
584
        if revision is not None:
582
585
            revision_ids.extend(rev.as_revision_id(b) for rev in revision)
681
684
                should_print=(not is_quiet()))
682
685
 
683
686
        if base_tree:
684
 
            base_tree.lock_read()
685
 
            self.add_cleanup(base_tree.unlock)
 
687
            self.add_cleanup(base_tree.lock_read().unlock)
686
688
        tree, file_list = tree_files_for_add(file_list)
687
689
        added, ignored = tree.smart_add(file_list, not
688
690
            no_recurse, action=action, save=not dry_run)
760
762
 
761
763
        revision = _get_one_revision('inventory', revision)
762
764
        work_tree, file_list = tree_files(file_list)
763
 
        work_tree.lock_read()
764
 
        self.add_cleanup(work_tree.unlock)
 
765
        self.add_cleanup(work_tree.lock_read().unlock)
765
766
        if revision is not None:
766
767
            tree = revision.as_tree(work_tree.branch)
767
768
 
768
769
            extra_trees = [work_tree]
769
 
            tree.lock_read()
770
 
            self.add_cleanup(tree.unlock)
 
770
            self.add_cleanup(tree.lock_read().unlock)
771
771
        else:
772
772
            tree = work_tree
773
773
            extra_trees = []
833
833
        if len(names_list) < 2:
834
834
            raise errors.BzrCommandError("missing file argument")
835
835
        tree, rel_names = tree_files(names_list, canonicalize=False)
836
 
        tree.lock_tree_write()
837
 
        self.add_cleanup(tree.unlock)
 
836
        self.add_cleanup(tree.lock_tree_write().unlock)
838
837
        self._run(tree, names_list, rel_names, after)
839
838
 
840
839
    def run_auto(self, names_list, after, dry_run):
845
844
            raise errors.BzrCommandError('--after cannot be specified with'
846
845
                                         ' --auto.')
847
846
        work_tree, file_list = tree_files(names_list, default_branch='.')
848
 
        work_tree.lock_tree_write()
849
 
        self.add_cleanup(work_tree.unlock)
 
847
        self.add_cleanup(work_tree.lock_tree_write().unlock)
850
848
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
851
849
 
852
850
    def _run(self, tree, names_list, rel_names, after):
960
958
    takes_options = ['remember', 'overwrite', 'revision',
961
959
        custom_help('verbose',
962
960
            help='Show logs of pulled revisions.'),
963
 
        Option('directory',
 
961
        custom_help('directory',
964
962
            help='Branch to pull into, '
965
 
                 'rather than the one containing the working directory.',
966
 
            short_name='d',
967
 
            type=unicode,
968
 
            ),
 
963
                 'rather than the one containing the working directory.'),
969
964
        Option('local',
970
965
            help="Perform a local pull in a bound "
971
966
                 "branch.  Local pulls are not applied to "
986
981
        try:
987
982
            tree_to = WorkingTree.open_containing(directory)[0]
988
983
            branch_to = tree_to.branch
989
 
            tree_to.lock_write()
990
 
            self.add_cleanup(tree_to.unlock)
 
984
            self.add_cleanup(tree_to.lock_write().unlock)
991
985
        except errors.NoWorkingTree:
992
986
            tree_to = None
993
987
            branch_to = Branch.open_containing(directory)[0]
994
 
            branch_to.lock_write()
995
 
            self.add_cleanup(branch_to.unlock)
 
988
            self.add_cleanup(branch_to.lock_write().unlock)
996
989
 
997
990
        if local and not branch_to.get_bound_location():
998
991
            raise errors.LocalRequiresBoundBranch()
1029
1022
        else:
1030
1023
            branch_from = Branch.open(location,
1031
1024
                possible_transports=possible_transports)
1032
 
            branch_from.lock_read()
1033
 
            self.add_cleanup(branch_from.unlock)
 
1025
            self.add_cleanup(branch_from.lock_read().unlock)
1034
1026
 
1035
1027
            if branch_to.get_parent() is None or remember:
1036
1028
                branch_to.set_parent(branch_from.base)
1088
1080
        Option('create-prefix',
1089
1081
               help='Create the path leading up to the branch '
1090
1082
                    'if it does not already exist.'),
1091
 
        Option('directory',
 
1083
        custom_help('directory',
1092
1084
            help='Branch to push from, '
1093
 
                 'rather than the one containing the working directory.',
1094
 
            short_name='d',
1095
 
            type=unicode,
1096
 
            ),
 
1085
                 'rather than the one containing the working directory.'),
1097
1086
        Option('use-existing-dir',
1098
1087
               help='By default push will fail if the target'
1099
1088
                    ' directory exists, but does not already'
1219
1208
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1220
1209
            from_location)
1221
1210
        revision = _get_one_revision('branch', revision)
1222
 
        br_from.lock_read()
1223
 
        self.add_cleanup(br_from.unlock)
 
1211
        self.add_cleanup(br_from.lock_read().unlock)
1224
1212
        if revision is not None:
1225
1213
            revision_id = revision.as_revision_id(br_from)
1226
1214
        else:
1366
1354
    @display_command
1367
1355
    def run(self, dir=u'.'):
1368
1356
        tree = WorkingTree.open_containing(dir)[0]
1369
 
        tree.lock_read()
1370
 
        self.add_cleanup(tree.unlock)
 
1357
        self.add_cleanup(tree.lock_read().unlock)
1371
1358
        new_inv = tree.inventory
1372
1359
        old_tree = tree.basis_tree()
1373
 
        old_tree.lock_read()
1374
 
        self.add_cleanup(old_tree.unlock)
 
1360
        self.add_cleanup(old_tree.lock_read().unlock)
1375
1361
        old_inv = old_tree.inventory
1376
1362
        renames = []
1377
1363
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1415
1401
        master = branch.get_master_branch(
1416
1402
            possible_transports=possible_transports)
1417
1403
        if master is not None:
1418
 
            tree.lock_write()
1419
1404
            branch_location = master.base
 
1405
            tree.lock_write()
1420
1406
        else:
 
1407
            branch_location = tree.branch.base
1421
1408
            tree.lock_tree_write()
1422
 
            branch_location = tree.branch.base
1423
1409
        self.add_cleanup(tree.unlock)
1424
1410
        # get rid of the final '/' and be ready for display
1425
1411
        branch_location = urlutils.unescape_for_display(
1545
1531
        if file_list is not None:
1546
1532
            file_list = [f for f in file_list]
1547
1533
 
1548
 
        tree.lock_write()
1549
 
        self.add_cleanup(tree.unlock)
 
1534
        self.add_cleanup(tree.lock_write().unlock)
1550
1535
        # Heuristics should probably all move into tree.remove_smart or
1551
1536
        # some such?
1552
1537
        if new:
1985
1970
         old_branch, new_branch,
1986
1971
         specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1987
1972
            file_list, revision, old, new, self.add_cleanup, apply_view=True)
 
1973
        # GNU diff on Windows uses ANSI encoding for filenames
 
1974
        path_encoding = osutils.get_diff_header_encoding()
1988
1975
        return show_diff_trees(old_tree, new_tree, sys.stdout,
1989
1976
                               specific_files=specific_files,
1990
1977
                               external_diff_options=diff_options,
1991
1978
                               old_label=old_label, new_label=new_label,
1992
 
                               extra_trees=extra_trees, using=using,
 
1979
                               extra_trees=extra_trees,
 
1980
                               path_encoding=path_encoding,
 
1981
                               using=using,
1993
1982
                               format_cls=format)
1994
1983
 
1995
1984
 
2003
1992
    # level of effort but possibly much less IO.  (Or possibly not,
2004
1993
    # if the directories are very large...)
2005
1994
    _see_also = ['status', 'ls']
2006
 
    takes_options = ['show-ids']
 
1995
    takes_options = ['directory', 'show-ids']
2007
1996
 
2008
1997
    @display_command
2009
 
    def run(self, show_ids=False):
2010
 
        tree = WorkingTree.open_containing(u'.')[0]
2011
 
        tree.lock_read()
2012
 
        self.add_cleanup(tree.unlock)
 
1998
    def run(self, show_ids=False, directory=u'.'):
 
1999
        tree = WorkingTree.open_containing(directory)[0]
 
2000
        self.add_cleanup(tree.lock_read().unlock)
2013
2001
        old = tree.basis_tree()
2014
 
        old.lock_read()
2015
 
        self.add_cleanup(old.unlock)
 
2002
        self.add_cleanup(old.lock_read().unlock)
2016
2003
        for path, ie in old.inventory.iter_entries():
2017
2004
            if not tree.has_id(ie.file_id):
2018
2005
                self.outf.write(path)
2028
2015
 
2029
2016
    hidden = True
2030
2017
    _see_also = ['status', 'ls']
2031
 
    takes_options = [
2032
 
            Option('null',
2033
 
                   help='Write an ascii NUL (\\0) separator '
2034
 
                   'between files rather than a newline.')
2035
 
            ]
 
2018
    takes_options = ['directory', 'null']
2036
2019
 
2037
2020
    @display_command
2038
 
    def run(self, null=False):
2039
 
        tree = WorkingTree.open_containing(u'.')[0]
 
2021
    def run(self, null=False, directory=u'.'):
 
2022
        tree = WorkingTree.open_containing(directory)[0]
2040
2023
        td = tree.changes_from(tree.basis_tree())
2041
2024
        for path, id, kind, text_modified, meta_modified in td.modified:
2042
2025
            if null:
2051
2034
 
2052
2035
    hidden = True
2053
2036
    _see_also = ['status', 'ls']
2054
 
    takes_options = [
2055
 
            Option('null',
2056
 
                   help='Write an ascii NUL (\\0) separator '
2057
 
                   'between files rather than a newline.')
2058
 
            ]
 
2037
    takes_options = ['directory', 'null']
2059
2038
 
2060
2039
    @display_command
2061
 
    def run(self, null=False):
2062
 
        wt = WorkingTree.open_containing(u'.')[0]
2063
 
        wt.lock_read()
2064
 
        self.add_cleanup(wt.unlock)
 
2040
    def run(self, null=False, directory=u'.'):
 
2041
        wt = WorkingTree.open_containing(directory)[0]
 
2042
        self.add_cleanup(wt.lock_read().unlock)
2065
2043
        basis = wt.basis_tree()
2066
 
        basis.lock_read()
2067
 
        self.add_cleanup(basis.unlock)
 
2044
        self.add_cleanup(basis.lock_read().unlock)
2068
2045
        basis_inv = basis.inventory
2069
2046
        inv = wt.inventory
2070
2047
        for file_id in inv:
2073
2050
            if inv.is_root(file_id) and len(basis_inv) == 0:
2074
2051
                continue
2075
2052
            path = inv.id2path(file_id)
2076
 
            if not os.access(osutils.abspath(path), os.F_OK):
 
2053
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2077
2054
                continue
2078
2055
            if null:
2079
2056
                self.outf.write(path + '\0')
2279
2256
                   help='Show just the specified revision.'
2280
2257
                   ' See also "help revisionspec".'),
2281
2258
            'log-format',
 
2259
            RegistryOption('authors',
 
2260
                'What names to list as authors - first, all or committer.',
 
2261
                title='Authors',
 
2262
                lazy_registry=('bzrlib.log', 'author_list_registry'),
 
2263
            ),
2282
2264
            Option('levels',
2283
2265
                   short_name='n',
2284
2266
                   help='Number of levels to display - 0 for all, 1 for flat.',
2319
2301
            limit=None,
2320
2302
            show_diff=False,
2321
2303
            include_merges=False,
 
2304
            authors=None,
2322
2305
            exclude_common_ancestry=False,
2323
2306
            ):
2324
2307
        from bzrlib.log import (
2352
2335
        if file_list:
2353
2336
            # find the file ids to log and check for directory filtering
2354
2337
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2355
 
                revision, file_list)
2356
 
            self.add_cleanup(b.unlock)
 
2338
                revision, file_list, self.add_cleanup)
2357
2339
            for relpath, file_id, kind in file_info_list:
2358
2340
                if file_id is None:
2359
2341
                    raise errors.BzrCommandError(
2377
2359
                location = '.'
2378
2360
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2379
2361
            b = dir.open_branch()
2380
 
            b.lock_read()
2381
 
            self.add_cleanup(b.unlock)
 
2362
            self.add_cleanup(b.lock_read().unlock)
2382
2363
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2383
2364
 
2384
2365
        # Decide on the type of delta & diff filtering to use
2404
2385
                        show_timezone=timezone,
2405
2386
                        delta_format=get_verbosity_level(),
2406
2387
                        levels=levels,
2407
 
                        show_advice=levels is None)
 
2388
                        show_advice=levels is None,
 
2389
                        author_list_handler=authors)
2408
2390
 
2409
2391
        # Choose the algorithm for doing the logging. It's annoying
2410
2392
        # having multiple code paths like this but necessary until
2508
2490
        tree, relpath = WorkingTree.open_containing(filename)
2509
2491
        file_id = tree.path2id(relpath)
2510
2492
        b = tree.branch
2511
 
        b.lock_read()
2512
 
        self.add_cleanup(b.unlock)
 
2493
        self.add_cleanup(b.lock_read().unlock)
2513
2494
        touching_revs = log.find_touching_revisions(b, file_id)
2514
2495
        for revno, revision_id, what in touching_revs:
2515
2496
            self.outf.write("%6d %s\n" % (revno, what))
2528
2509
                   help='Recurse into subdirectories.'),
2529
2510
            Option('from-root',
2530
2511
                   help='Print paths relative to the root of the branch.'),
2531
 
            Option('unknown', help='Print unknown files.'),
 
2512
            Option('unknown', short_name='u',
 
2513
                help='Print unknown files.'),
2532
2514
            Option('versioned', help='Print versioned files.',
2533
2515
                   short_name='V'),
2534
 
            Option('ignored', help='Print ignored files.'),
2535
 
            Option('null',
2536
 
                   help='Write an ascii NUL (\\0) separator '
2537
 
                   'between files rather than a newline.'),
2538
 
            Option('kind',
 
2516
            Option('ignored', short_name='i',
 
2517
                help='Print ignored files.'),
 
2518
            Option('kind', short_name='k',
2539
2519
                   help='List entries of a particular kind: file, directory, symlink.',
2540
2520
                   type=unicode),
 
2521
            'null',
2541
2522
            'show-ids',
 
2523
            'directory',
2542
2524
            ]
2543
2525
    @display_command
2544
2526
    def run(self, revision=None, verbose=False,
2545
2527
            recursive=False, from_root=False,
2546
2528
            unknown=False, versioned=False, ignored=False,
2547
 
            null=False, kind=None, show_ids=False, path=None):
 
2529
            null=False, kind=None, show_ids=False, path=None, directory=None):
2548
2530
 
2549
2531
        if kind and kind not in ('file', 'directory', 'symlink'):
2550
2532
            raise errors.BzrCommandError('invalid kind specified')
2562
2544
                raise errors.BzrCommandError('cannot specify both --from-root'
2563
2545
                                             ' and PATH')
2564
2546
            fs_path = path
2565
 
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2566
 
            fs_path)
 
2547
        tree, branch, relpath = \
 
2548
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
2567
2549
 
2568
2550
        # Calculate the prefix to use
2569
2551
        prefix = None
2584
2566
                view_str = views.view_display_str(view_files)
2585
2567
                note("Ignoring files outside view. View is %s" % view_str)
2586
2568
 
2587
 
        tree.lock_read()
2588
 
        self.add_cleanup(tree.unlock)
 
2569
        self.add_cleanup(tree.lock_read().unlock)
2589
2570
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2590
2571
            from_dir=relpath, recursive=recursive):
2591
2572
            # Apply additional masking
2638
2619
 
2639
2620
    hidden = True
2640
2621
    _see_also = ['ls']
 
2622
    takes_options = ['directory']
2641
2623
 
2642
2624
    @display_command
2643
 
    def run(self):
2644
 
        for f in WorkingTree.open_containing(u'.')[0].unknowns():
 
2625
    def run(self, directory=u'.'):
 
2626
        for f in WorkingTree.open_containing(directory)[0].unknowns():
2645
2627
            self.outf.write(osutils.quotefn(f) + '\n')
2646
2628
 
2647
2629
 
2712
2694
 
2713
2695
    _see_also = ['status', 'ignored', 'patterns']
2714
2696
    takes_args = ['name_pattern*']
2715
 
    takes_options = [
 
2697
    takes_options = ['directory',
2716
2698
        Option('default-rules',
2717
2699
               help='Display the default ignore rules that bzr uses.')
2718
2700
        ]
2719
2701
 
2720
 
    def run(self, name_pattern_list=None, default_rules=None):
 
2702
    def run(self, name_pattern_list=None, default_rules=None,
 
2703
            directory=u'.'):
2721
2704
        from bzrlib import ignores
2722
2705
        if default_rules is not None:
2723
2706
            # dump the default rules and exit
2734
2717
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2735
2718
                raise errors.BzrCommandError(
2736
2719
                    "NAME_PATTERN should not be an absolute path")
2737
 
        tree, relpath = WorkingTree.open_containing(u'.')
 
2720
        tree, relpath = WorkingTree.open_containing(directory)
2738
2721
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2739
2722
        ignored = globbing.Globster(name_pattern_list)
2740
2723
        matches = []
2766
2749
 
2767
2750
    encoding_type = 'replace'
2768
2751
    _see_also = ['ignore', 'ls']
 
2752
    takes_options = ['directory']
2769
2753
 
2770
2754
    @display_command
2771
 
    def run(self):
2772
 
        tree = WorkingTree.open_containing(u'.')[0]
2773
 
        tree.lock_read()
2774
 
        self.add_cleanup(tree.unlock)
 
2755
    def run(self, directory=u'.'):
 
2756
        tree = WorkingTree.open_containing(directory)[0]
 
2757
        self.add_cleanup(tree.lock_read().unlock)
2775
2758
        for path, file_class, kind, file_id, entry in tree.list_files():
2776
2759
            if file_class != 'I':
2777
2760
                continue
2788
2771
    """
2789
2772
    hidden = True
2790
2773
    takes_args = ['revno']
 
2774
    takes_options = ['directory']
2791
2775
 
2792
2776
    @display_command
2793
 
    def run(self, revno):
 
2777
    def run(self, revno, directory=u'.'):
2794
2778
        try:
2795
2779
            revno = int(revno)
2796
2780
        except ValueError:
2797
2781
            raise errors.BzrCommandError("not a valid revision-number: %r"
2798
2782
                                         % revno)
2799
 
        revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
 
2783
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2800
2784
        self.outf.write("%s\n" % revid)
2801
2785
 
2802
2786
 
2829
2813
      =================       =========================
2830
2814
    """
2831
2815
    takes_args = ['dest', 'branch_or_subdir?']
2832
 
    takes_options = [
 
2816
    takes_options = ['directory',
2833
2817
        Option('format',
2834
2818
               help="Type of file to export to.",
2835
2819
               type=unicode),
2844
2828
                    'revision in which it was changed.'),
2845
2829
        ]
2846
2830
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2847
 
        root=None, filters=False, per_file_timestamps=False):
 
2831
        root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2848
2832
        from bzrlib.export import export
2849
2833
 
2850
2834
        if branch_or_subdir is None:
2851
 
            tree = WorkingTree.open_containing(u'.')[0]
 
2835
            tree = WorkingTree.open_containing(directory)[0]
2852
2836
            b = tree.branch
2853
2837
            subdir = None
2854
2838
        else:
2873
2857
    """
2874
2858
 
2875
2859
    _see_also = ['ls']
2876
 
    takes_options = [
 
2860
    takes_options = ['directory',
2877
2861
        Option('name-from-revision', help='The path name in the old tree.'),
2878
2862
        Option('filters', help='Apply content filters to display the '
2879
2863
                'convenience form.'),
2884
2868
 
2885
2869
    @display_command
2886
2870
    def run(self, filename, revision=None, name_from_revision=False,
2887
 
            filters=False):
 
2871
            filters=False, directory=None):
2888
2872
        if revision is not None and len(revision) != 1:
2889
2873
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2890
2874
                                         " one revision specifier")
2891
2875
        tree, branch, relpath = \
2892
 
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2893
 
        branch.lock_read()
2894
 
        self.add_cleanup(branch.unlock)
 
2876
            _open_directory_or_containing_tree_or_branch(filename, directory)
 
2877
        self.add_cleanup(branch.lock_read().unlock)
2895
2878
        return self._run(tree, branch, relpath, filename, revision,
2896
2879
                         name_from_revision, filters)
2897
2880
 
2900
2883
        if tree is None:
2901
2884
            tree = b.basis_tree()
2902
2885
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2903
 
        rev_tree.lock_read()
2904
 
        self.add_cleanup(rev_tree.unlock)
 
2886
        self.add_cleanup(rev_tree.lock_read().unlock)
2905
2887
 
2906
2888
        old_file_id = rev_tree.path2id(relpath)
2907
2889
 
3169
3151
        def get_message(commit_obj):
3170
3152
            """Callback to get commit message"""
3171
3153
            if file:
3172
 
                my_message = codecs.open(
3173
 
                    file, 'rt', osutils.get_user_encoding()).read()
 
3154
                f = codecs.open(file, 'rt', osutils.get_user_encoding())
 
3155
                try:
 
3156
                    my_message = f.read()
 
3157
                finally:
 
3158
                    f.close()
3174
3159
            elif message is not None:
3175
3160
                my_message = message
3176
3161
            else:
3330
3315
 
3331
3316
            bzr whoami "Frank Chu <fchu@example.com>"
3332
3317
    """
3333
 
    takes_options = [ Option('email',
 
3318
    takes_options = [ 'directory',
 
3319
                      Option('email',
3334
3320
                             help='Display email address only.'),
3335
3321
                      Option('branch',
3336
3322
                             help='Set identity for the current branch instead of '
3340
3326
    encoding_type = 'replace'
3341
3327
 
3342
3328
    @display_command
3343
 
    def run(self, email=False, branch=False, name=None):
 
3329
    def run(self, email=False, branch=False, name=None, directory=None):
3344
3330
        if name is None:
3345
 
            # use branch if we're inside one; otherwise global config
3346
 
            try:
3347
 
                c = Branch.open_containing('.')[0].get_config()
3348
 
            except errors.NotBranchError:
3349
 
                c = config.GlobalConfig()
 
3331
            if directory is None:
 
3332
                # use branch if we're inside one; otherwise global config
 
3333
                try:
 
3334
                    c = Branch.open_containing(u'.')[0].get_config()
 
3335
                except errors.NotBranchError:
 
3336
                    c = config.GlobalConfig()
 
3337
            else:
 
3338
                c = Branch.open(directory).get_config()
3350
3339
            if email:
3351
3340
                self.outf.write(c.user_email() + '\n')
3352
3341
            else:
3362
3351
 
3363
3352
        # use global config unless --branch given
3364
3353
        if branch:
3365
 
            c = Branch.open_containing('.')[0].get_config()
 
3354
            if directory is None:
 
3355
                c = Branch.open_containing(u'.')[0].get_config()
 
3356
            else:
 
3357
                c = Branch.open(directory).get_config()
3366
3358
        else:
3367
3359
            c = config.GlobalConfig()
3368
3360
        c.set_user_option('email', name)
3380
3372
 
3381
3373
    _see_also = ['info']
3382
3374
    takes_args = ['nickname?']
3383
 
    def run(self, nickname=None):
3384
 
        branch = Branch.open_containing(u'.')[0]
 
3375
    takes_options = ['directory']
 
3376
    def run(self, nickname=None, directory=u'.'):
 
3377
        branch = Branch.open_containing(directory)[0]
3385
3378
        if nickname is None:
3386
3379
            self.printme(branch)
3387
3380
        else:
3612
3605
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3613
3606
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
3614
3607
            # stdout, which would corrupt the subunit stream. 
3615
 
            if sys.platform == "win32" and sys.stdout.fileno() >= 0:
 
3608
            # FIXME: This has been fixed in subunit trunk (>0.0.5) so the
 
3609
            # following code can be deleted when it's sufficiently deployed
 
3610
            # -- vila/mgz 20100514
 
3611
            if (sys.platform == "win32"
 
3612
                and getattr(sys.stdout, 'fileno', None) is not None):
3616
3613
                import msvcrt
3617
3614
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3618
3615
        if parallel:
3690
3687
 
3691
3688
        branch1 = Branch.open_containing(branch)[0]
3692
3689
        branch2 = Branch.open_containing(other)[0]
3693
 
        branch1.lock_read()
3694
 
        self.add_cleanup(branch1.unlock)
3695
 
        branch2.lock_read()
3696
 
        self.add_cleanup(branch2.unlock)
 
3690
        self.add_cleanup(branch1.lock_read().unlock)
 
3691
        self.add_cleanup(branch2.lock_read().unlock)
3697
3692
        last1 = ensure_null(branch1.last_revision())
3698
3693
        last2 = ensure_null(branch2.last_revision())
3699
3694
 
3793
3788
                ' completely merged into the source, pull from the'
3794
3789
                ' source rather than merging.  When this happens,'
3795
3790
                ' you do not need to commit the result.'),
3796
 
        Option('directory',
 
3791
        custom_help('directory',
3797
3792
               help='Branch to merge into, '
3798
 
                    'rather than the one containing the working directory.',
3799
 
               short_name='d',
3800
 
               type=unicode,
3801
 
               ),
 
3793
                    'rather than the one containing the working directory.'),
3802
3794
        Option('preview', help='Instead of merging, show a diff of the'
3803
3795
               ' merge.'),
3804
3796
        Option('interactive', help='Select changes interactively.',
3837
3829
            unversioned_filter=tree.is_ignored, view_info=view_info)
3838
3830
        pb = ui.ui_factory.nested_progress_bar()
3839
3831
        self.add_cleanup(pb.finished)
3840
 
        tree.lock_write()
3841
 
        self.add_cleanup(tree.unlock)
 
3832
        self.add_cleanup(tree.lock_write().unlock)
3842
3833
        if location is not None:
3843
3834
            try:
3844
3835
                mergeable = bundle.read_mergeable_from_url(location,
3905
3896
    def _do_preview(self, merger):
3906
3897
        from bzrlib.diff import show_diff_trees
3907
3898
        result_tree = self._get_preview(merger)
 
3899
        path_encoding = osutils.get_diff_header_encoding()
3908
3900
        show_diff_trees(merger.this_tree, result_tree, self.outf,
3909
 
                        old_label='', new_label='')
 
3901
                        old_label='', new_label='',
 
3902
                        path_encoding=path_encoding)
3910
3903
 
3911
3904
    def _do_merge(self, merger, change_reporter, allow_pending, verified):
3912
3905
        merger.change_reporter = change_reporter
4100
4093
        if merge_type is None:
4101
4094
            merge_type = _mod_merge.Merge3Merger
4102
4095
        tree, file_list = tree_files(file_list)
4103
 
        tree.lock_write()
4104
 
        self.add_cleanup(tree.unlock)
 
4096
        self.add_cleanup(tree.lock_write().unlock)
4105
4097
        parents = tree.get_parent_ids()
4106
4098
        if len(parents) != 2:
4107
4099
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
4217
4209
    def run(self, revision=None, no_backup=False, file_list=None,
4218
4210
            forget_merges=None):
4219
4211
        tree, file_list = tree_files(file_list)
4220
 
        tree.lock_tree_write()
4221
 
        self.add_cleanup(tree.unlock)
 
4212
        self.add_cleanup(tree.lock_tree_write().unlock)
4222
4213
        if forget_merges:
4223
4214
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4224
4215
        else:
4313
4304
    _see_also = ['merge', 'pull']
4314
4305
    takes_args = ['other_branch?']
4315
4306
    takes_options = [
 
4307
        'directory',
4316
4308
        Option('reverse', 'Reverse the order of revisions.'),
4317
4309
        Option('mine-only',
4318
4310
               'Display changes in the local branch only.'),
4340
4332
            theirs_only=False,
4341
4333
            log_format=None, long=False, short=False, line=False,
4342
4334
            show_ids=False, verbose=False, this=False, other=False,
4343
 
            include_merges=False, revision=None, my_revision=None):
 
4335
            include_merges=False, revision=None, my_revision=None,
 
4336
            directory=u'.'):
4344
4337
        from bzrlib.missing import find_unmerged, iter_log_revisions
4345
4338
        def message(s):
4346
4339
            if not is_quiet():
4359
4352
        elif theirs_only:
4360
4353
            restrict = 'remote'
4361
4354
 
4362
 
        local_branch = Branch.open_containing(u".")[0]
4363
 
        local_branch.lock_read()
4364
 
        self.add_cleanup(local_branch.unlock)
 
4355
        local_branch = Branch.open_containing(directory)[0]
 
4356
        self.add_cleanup(local_branch.lock_read().unlock)
4365
4357
 
4366
4358
        parent = local_branch.get_parent()
4367
4359
        if other_branch is None:
4378
4370
        if remote_branch.base == local_branch.base:
4379
4371
            remote_branch = local_branch
4380
4372
        else:
4381
 
            remote_branch.lock_read()
4382
 
            self.add_cleanup(remote_branch.unlock)
 
4373
            self.add_cleanup(remote_branch.lock_read().unlock)
4383
4374
 
4384
4375
        local_revid_range = _revision_range_to_revid_range(
4385
4376
            _get_revision_range(my_revision, local_branch,
4440
4431
            message("Branches are up to date.\n")
4441
4432
        self.cleanup_now()
4442
4433
        if not status_code and parent is None and other_branch is not None:
4443
 
            local_branch.lock_write()
4444
 
            self.add_cleanup(local_branch.unlock)
 
4434
            self.add_cleanup(local_branch.lock_write().unlock)
4445
4435
            # handle race conditions - a parent might be set while we run.
4446
4436
            if local_branch.get_parent() is None:
4447
4437
                local_branch.set_parent(remote_branch.base)
4547
4537
            b = Branch.open_containing(branch)[0]
4548
4538
        else:
4549
4539
            b = Branch.open(branch)
4550
 
        b.lock_read()
4551
 
        self.add_cleanup(b.unlock)
 
4540
        self.add_cleanup(b.lock_read().unlock)
4552
4541
        if revision is None:
4553
4542
            rev_id = b.last_revision()
4554
4543
        else:
4578
4567
                     Option('long', help='Show commit date in annotations.'),
4579
4568
                     'revision',
4580
4569
                     'show-ids',
 
4570
                     'directory',
4581
4571
                     ]
4582
4572
    encoding_type = 'exact'
4583
4573
 
4584
4574
    @display_command
4585
4575
    def run(self, filename, all=False, long=False, revision=None,
4586
 
            show_ids=False):
 
4576
            show_ids=False, directory=None):
4587
4577
        from bzrlib.annotate import annotate_file, annotate_file_tree
4588
4578
        wt, branch, relpath = \
4589
 
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
 
4579
            _open_directory_or_containing_tree_or_branch(filename, directory)
4590
4580
        if wt is not None:
4591
 
            wt.lock_read()
4592
 
            self.add_cleanup(wt.unlock)
 
4581
            self.add_cleanup(wt.lock_read().unlock)
4593
4582
        else:
4594
 
            branch.lock_read()
4595
 
            self.add_cleanup(branch.unlock)
 
4583
            self.add_cleanup(branch.lock_read().unlock)
4596
4584
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4597
 
        tree.lock_read()
4598
 
        self.add_cleanup(tree.unlock)
 
4585
        self.add_cleanup(tree.lock_read().unlock)
4599
4586
        if wt is not None:
4600
4587
            file_id = wt.path2id(relpath)
4601
4588
        else:
4619
4606
 
4620
4607
    hidden = True # is this right ?
4621
4608
    takes_args = ['revision_id*']
4622
 
    takes_options = ['revision']
 
4609
    takes_options = ['directory', 'revision']
4623
4610
 
4624
 
    def run(self, revision_id_list=None, revision=None):
 
4611
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
4625
4612
        if revision_id_list is not None and revision is not None:
4626
4613
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4627
4614
        if revision_id_list is None and revision is None:
4628
4615
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4629
 
        b = WorkingTree.open_containing(u'.')[0].branch
4630
 
        b.lock_write()
4631
 
        self.add_cleanup(b.unlock)
 
4616
        b = WorkingTree.open_containing(directory)[0].branch
 
4617
        self.add_cleanup(b.lock_write().unlock)
4632
4618
        return self._run(b, revision_id_list, revision)
4633
4619
 
4634
4620
    def _run(self, b, revision_id_list, revision):
4693
4679
 
4694
4680
    _see_also = ['checkouts', 'unbind']
4695
4681
    takes_args = ['location?']
4696
 
    takes_options = []
 
4682
    takes_options = ['directory']
4697
4683
 
4698
 
    def run(self, location=None):
4699
 
        b, relpath = Branch.open_containing(u'.')
 
4684
    def run(self, location=None, directory=u'.'):
 
4685
        b, relpath = Branch.open_containing(directory)
4700
4686
        if location is None:
4701
4687
            try:
4702
4688
                location = b.get_old_bound_location()
4729
4715
 
4730
4716
    _see_also = ['checkouts', 'bind']
4731
4717
    takes_args = []
4732
 
    takes_options = []
 
4718
    takes_options = ['directory']
4733
4719
 
4734
 
    def run(self):
4735
 
        b, relpath = Branch.open_containing(u'.')
 
4720
    def run(self, directory=u'.'):
 
4721
        b, relpath = Branch.open_containing(directory)
4736
4722
        if not b.unbind():
4737
4723
            raise errors.BzrCommandError('Local branch is not bound')
4738
4724
 
4784
4770
            b = control.open_branch()
4785
4771
 
4786
4772
        if tree is not None:
4787
 
            tree.lock_write()
4788
 
            self.add_cleanup(tree.unlock)
 
4773
            self.add_cleanup(tree.lock_write().unlock)
4789
4774
        else:
4790
 
            b.lock_write()
4791
 
            self.add_cleanup(b.unlock)
 
4775
            self.add_cleanup(b.lock_write().unlock)
4792
4776
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4793
4777
 
4794
4778
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4902
4886
                    'result in a dynamically allocated port.  The default port '
4903
4887
                    'depends on the protocol.',
4904
4888
               type=str),
4905
 
        Option('directory',
4906
 
               help='Serve contents of this directory.',
4907
 
               type=unicode),
 
4889
        custom_help('directory',
 
4890
               help='Serve contents of this directory.'),
4908
4891
        Option('allow-writes',
4909
4892
               help='By default the server is a readonly server.  Supplying '
4910
4893
                    '--allow-writes enables write access to the contents of '
5046
5029
    _see_also = ['send']
5047
5030
 
5048
5031
    takes_options = [
 
5032
        'directory',
5049
5033
        RegistryOption.from_kwargs('patch-type',
5050
5034
            'The type of patch to include in the directive.',
5051
5035
            title='Patch type',
5064
5048
    encoding_type = 'exact'
5065
5049
 
5066
5050
    def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5067
 
            sign=False, revision=None, mail_to=None, message=None):
 
5051
            sign=False, revision=None, mail_to=None, message=None,
 
5052
            directory=u'.'):
5068
5053
        from bzrlib.revision import ensure_null, NULL_REVISION
5069
5054
        include_patch, include_bundle = {
5070
5055
            'plain': (False, False),
5071
5056
            'diff': (True, False),
5072
5057
            'bundle': (True, True),
5073
5058
            }[patch_type]
5074
 
        branch = Branch.open('.')
 
5059
        branch = Branch.open(directory)
5075
5060
        stored_submit_branch = branch.get_submit_branch()
5076
5061
        if submit_branch is None:
5077
5062
            submit_branch = stored_submit_branch
5162
5147
    given, in which case it is sent to a file.
5163
5148
 
5164
5149
    Mail is sent using your preferred mail program.  This should be transparent
5165
 
    on Windows (it uses MAPI).  On Linux, it requires the xdg-email utility.
 
5150
    on Windows (it uses MAPI).  On Unix, it requires the xdg-email utility.
5166
5151
    If the preferred client can't be found (or used), your editor will be used.
5167
5152
 
5168
5153
    To use a specific mail program, set the mail_client configuration option.
5339
5324
        Option('delete',
5340
5325
            help='Delete this tag rather than placing it.',
5341
5326
            ),
5342
 
        Option('directory',
5343
 
            help='Branch in which to place the tag.',
5344
 
            short_name='d',
5345
 
            type=unicode,
5346
 
            ),
 
5327
        custom_help('directory',
 
5328
            help='Branch in which to place the tag.'),
5347
5329
        Option('force',
5348
5330
            help='Replace existing tags.',
5349
5331
            ),
5357
5339
            revision=None,
5358
5340
            ):
5359
5341
        branch, relpath = Branch.open_containing(directory)
5360
 
        branch.lock_write()
5361
 
        self.add_cleanup(branch.unlock)
 
5342
        self.add_cleanup(branch.lock_write().unlock)
5362
5343
        if delete:
5363
5344
            if tag_name is None:
5364
5345
                raise errors.BzrCommandError("No tag specified to delete.")
5392
5373
 
5393
5374
    _see_also = ['tag']
5394
5375
    takes_options = [
5395
 
        Option('directory',
5396
 
            help='Branch whose tags should be displayed.',
5397
 
            short_name='d',
5398
 
            type=unicode,
5399
 
            ),
 
5376
        custom_help('directory',
 
5377
            help='Branch whose tags should be displayed.'),
5400
5378
        RegistryOption.from_kwargs('sort',
5401
5379
            'Sort tags by different criteria.', title='Sorting',
5402
5380
            alpha='Sort tags lexicographically (default).',
5419
5397
        if not tags:
5420
5398
            return
5421
5399
 
5422
 
        branch.lock_read()
5423
 
        self.add_cleanup(branch.unlock)
 
5400
        self.add_cleanup(branch.lock_read().unlock)
5424
5401
        if revision:
5425
5402
            graph = branch.repository.get_graph()
5426
5403
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5573
5550
    """
5574
5551
 
5575
5552
    takes_args = ['to_location?']
5576
 
    takes_options = [Option('force',
 
5553
    takes_options = ['directory',
 
5554
                     Option('force',
5577
5555
                        help='Switch even if local commits will be lost.'),
5578
5556
                     'revision',
5579
5557
                     Option('create-branch', short_name='b',
5582
5560
                    ]
5583
5561
 
5584
5562
    def run(self, to_location=None, force=False, create_branch=False,
5585
 
            revision=None):
 
5563
            revision=None, directory=u'.'):
5586
5564
        from bzrlib import switch
5587
 
        tree_location = '.'
 
5565
        tree_location = directory
5588
5566
        revision = _get_one_revision('switch', revision)
5589
5567
        control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5590
5568
        if to_location is None:
5591
5569
            if revision is None:
5592
5570
                raise errors.BzrCommandError('You must supply either a'
5593
5571
                                             ' revision or a location')
5594
 
            to_location = '.'
 
5572
            to_location = tree_location
5595
5573
        try:
5596
5574
            branch = control_dir.open_branch()
5597
5575
            had_explicit_nick = branch.get_config().has_explicit_nickname()
5872
5850
    takes_args = ['file*']
5873
5851
 
5874
5852
    takes_options = [
 
5853
        'directory',
5875
5854
        'revision',
5876
5855
        Option('all', help='Shelve all changes.'),
5877
5856
        'message',
5886
5865
    _see_also = ['unshelve']
5887
5866
 
5888
5867
    def run(self, revision=None, all=False, file_list=None, message=None,
5889
 
            writer=None, list=False, destroy=False):
 
5868
            writer=None, list=False, destroy=False, directory=u'.'):
5890
5869
        if list:
5891
5870
            return self.run_for_list()
5892
5871
        from bzrlib.shelf_ui import Shelver
5894
5873
            writer = bzrlib.option.diff_writer_registry.get()
5895
5874
        try:
5896
5875
            shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5897
 
                file_list, message, destroy=destroy)
 
5876
                file_list, message, destroy=destroy, directory=directory)
5898
5877
            try:
5899
5878
                shelver.run()
5900
5879
            finally:
5904
5883
 
5905
5884
    def run_for_list(self):
5906
5885
        tree = WorkingTree.open_containing('.')[0]
5907
 
        tree.lock_read()
5908
 
        self.add_cleanup(tree.unlock)
 
5886
        self.add_cleanup(tree.lock_read().unlock)
5909
5887
        manager = tree.get_shelf_manager()
5910
5888
        shelves = manager.active_shelves()
5911
5889
        if len(shelves) == 0:
5929
5907
 
5930
5908
    takes_args = ['shelf_id?']
5931
5909
    takes_options = [
 
5910
        'directory',
5932
5911
        RegistryOption.from_kwargs(
5933
5912
            'action', help="The action to perform.",
5934
5913
            enum_switch=False, value_switches=True,
5942
5921
    ]
5943
5922
    _see_also = ['shelve']
5944
5923
 
5945
 
    def run(self, shelf_id=None, action='apply'):
 
5924
    def run(self, shelf_id=None, action='apply', directory=u'.'):
5946
5925
        from bzrlib.shelf_ui import Unshelver
5947
 
        unshelver = Unshelver.from_args(shelf_id, action)
 
5926
        unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5948
5927
        try:
5949
5928
            unshelver.run()
5950
5929
        finally:
5966
5945
 
5967
5946
    To check what clean-tree will do, use --dry-run.
5968
5947
    """
5969
 
    takes_options = [Option('ignored', help='Delete all ignored files.'),
 
5948
    takes_options = ['directory',
 
5949
                     Option('ignored', help='Delete all ignored files.'),
5970
5950
                     Option('detritus', help='Delete conflict files, merge'
5971
5951
                            ' backups, and failed selftest dirs.'),
5972
5952
                     Option('unknown',
5975
5955
                            ' deleting them.'),
5976
5956
                     Option('force', help='Do not prompt before deleting.')]
5977
5957
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
5978
 
            force=False):
 
5958
            force=False, directory=u'.'):
5979
5959
        from bzrlib.clean_tree import clean_tree
5980
5960
        if not (unknown or ignored or detritus):
5981
5961
            unknown = True
5982
5962
        if dry_run:
5983
5963
            force = True
5984
 
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5985
 
                   dry_run=dry_run, no_prompt=force)
 
5964
        clean_tree(directory, unknown=unknown, ignored=ignored,
 
5965
                   detritus=detritus, dry_run=dry_run, no_prompt=force)
5986
5966
 
5987
5967
 
5988
5968
class cmd_reference(Command):