75
76
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
79
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
78
80
def tree_files(file_list, default_branch=u'.', canonicalize=True,
81
return internal_tree_files(file_list, default_branch, canonicalize,
83
except errors.FileInWrongBranch, e:
84
raise errors.BzrCommandError("%s is not in the same branch as %s" %
85
(e.path, file_list[0]))
82
return internal_tree_files(file_list, default_branch, canonicalize,
88
86
def tree_files_for_add(file_list):
153
151
# XXX: Bad function name; should possibly also be a class method of
154
152
# WorkingTree rather than a function.
153
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
155
154
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
156
155
apply_view=True):
157
156
"""Convert command-line paths to a WorkingTree and relative paths.
158
Deprecated: use WorkingTree.open_containing_paths instead.
159
160
This is typically used for command-line processors that take one or
160
161
more filenames, and infer the workingtree that contains them.
172
173
:return: workingtree, [relative_paths]
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()
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)
188
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
189
"""Convert file_list into a list of relpaths in tree.
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
199
if file_list is None:
201
if tree.supports_views() and apply_view:
202
view_files = tree.views.lookup_view()
206
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
207
# doesn't - fix that up here before we enter the loop.
209
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
212
for filename in file_list:
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)
175
return WorkingTree.open_containing_paths(
176
file_list, default_directory='.',
223
181
def _get_view_info_for_change_reporter(tree):
193
def _open_directory_or_containing_tree_or_branch(filename, directory):
194
"""Open the tree or branch containing the specified file, unless
195
the --directory option is used to specify a different branch."""
196
if directory is not None:
197
return (None, Branch.open(directory), filename)
198
return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
235
201
# TODO: Make sure no commands unconditionally use the working directory as a
236
202
# branch. If a filename argument is used, the first of them should be used to
237
203
# specify the branch. (Perhaps this can be factored out into some kind of
286
252
To skip the display of pending merge information altogether, use
287
253
the no-pending option or specify a file/directory.
289
If a revision argument is given, the status is calculated against
290
that revision, or between two revisions if two are provided.
255
To compare the working directory to a specific revision, pass a
256
single revision to the revision argument.
258
To see which files have changed in a specific revision, or between
259
two revisions, pass a revision range to the revision argument.
260
This will produce the same results as calling 'bzr diff --summarize'.
293
263
# TODO: --no-recurse, --recurse options
315
285
raise errors.BzrCommandError('bzr status --revision takes exactly'
316
286
' one or two revision specifiers')
318
tree, relfile_list = tree_files(file_list)
288
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
319
289
# Avoid asking for specific files when that is not needed.
320
290
if relfile_list == ['']:
321
291
relfile_list = None
353
323
self.outf.write(revtext.decode('utf-8'))
356
def run(self, revision_id=None, revision=None):
326
def run(self, revision_id=None, revision=None, directory=u'.'):
357
327
if revision_id is not None and revision is not None:
358
328
raise errors.BzrCommandError('You can only supply one of'
359
329
' revision_id or --revision')
360
330
if revision_id is None and revision is None:
361
331
raise errors.BzrCommandError('You must supply either'
362
332
' --revision or a revision_id')
363
b = WorkingTree.open_containing(u'.')[0].branch
333
b = WorkingTree.open_containing(directory)[0].branch
365
335
revisions = b.repository.revisions
366
336
if revisions is None:
504
474
if (working.has_changes()):
505
475
raise errors.UncommittedChanges(working)
476
if working.get_shelf_manager().last_shelf() is not None:
477
raise errors.ShelvedChanges(working)
507
479
if working.user_url != working.branch.user_url:
508
480
raise errors.BzrCommandError("You cannot remove the working tree"
552
524
takes_args = ['revision_info*']
553
525
takes_options = [
527
custom_help('directory',
556
528
help='Branch to examine, '
557
'rather than the one containing the working directory.',
529
'rather than the one containing the working directory.'),
561
530
Option('tree', help='Show revno of working tree'),
754
723
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
756
725
revision = _get_one_revision('inventory', revision)
757
work_tree, file_list = tree_files(file_list)
726
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
758
727
self.add_cleanup(work_tree.lock_read().unlock)
759
728
if revision is not None:
760
729
tree = revision.as_tree(work_tree.branch)
826
795
if len(names_list) < 2:
827
796
raise errors.BzrCommandError("missing file argument")
828
tree, rel_names = tree_files(names_list, canonicalize=False)
797
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
829
798
self.add_cleanup(tree.lock_tree_write().unlock)
830
799
self._run(tree, names_list, rel_names, after)
837
806
raise errors.BzrCommandError('--after cannot be specified with'
839
work_tree, file_list = tree_files(names_list, default_branch='.')
808
work_tree, file_list = WorkingTree.open_containing_paths(
809
names_list, default_directory='.')
840
810
self.add_cleanup(work_tree.lock_tree_write().unlock)
841
811
rename_map.RenameMap.guess_renames(work_tree, dry_run)
951
921
takes_options = ['remember', 'overwrite', 'revision',
952
922
custom_help('verbose',
953
923
help='Show logs of pulled revisions.'),
924
custom_help('directory',
955
925
help='Branch to pull into, '
956
'rather than the one containing the working directory.',
926
'rather than the one containing the working directory.'),
961
928
help="Perform a local pull in a bound "
962
929
"branch. Local pulls are not applied to "
963
930
"the master branch."
933
help="Show base revision text in conflicts.")
966
935
takes_args = ['location?']
967
936
encoding_type = 'replace'
969
938
def run(self, location=None, remember=False, overwrite=False,
970
939
revision=None, verbose=False,
971
directory=None, local=False):
940
directory=None, local=False,
972
942
# FIXME: too much stuff is in the command class
973
943
revision_id = None
983
953
branch_to = Branch.open_containing(directory)[0]
984
954
self.add_cleanup(branch_to.lock_write().unlock)
956
if tree_to is None and show_base:
957
raise errors.BzrCommandError("Need working tree for --show-base.")
986
959
if local and not branch_to.get_bound_location():
987
960
raise errors.LocalRequiresBoundBranch()
1033
1006
view_info=view_info)
1034
1007
result = tree_to.pull(
1035
1008
branch_from, overwrite, revision_id, change_reporter,
1036
possible_transports=possible_transports, local=local)
1009
possible_transports=possible_transports, local=local,
1010
show_base=show_base)
1038
1012
result = branch_to.pull(
1039
1013
branch_from, overwrite, revision_id, local=local)
1076
1050
Option('create-prefix',
1077
1051
help='Create the path leading up to the branch '
1078
1052
'if it does not already exist.'),
1053
custom_help('directory',
1080
1054
help='Branch to push from, '
1081
'rather than the one containing the working directory.',
1055
'rather than the one containing the working directory.'),
1085
1056
Option('use-existing-dir',
1086
1057
help='By default push will fail if the target'
1087
1058
' directory exists, but does not already'
1098
1069
Option('strict',
1099
1070
help='Refuse to push if there are uncommitted changes in'
1100
1071
' the working tree, --no-strict disables the check.'),
1073
help="Don't populate the working tree, even for protocols"
1074
" that support it."),
1102
1076
takes_args = ['location?']
1103
1077
encoding_type = 'replace'
1105
1079
def run(self, location=None, remember=False, overwrite=False,
1106
1080
create_prefix=False, verbose=False, revision=None,
1107
1081
use_existing_dir=False, directory=None, stacked_on=None,
1108
stacked=False, strict=None):
1082
stacked=False, strict=None, no_tree=False):
1109
1083
from bzrlib.push import _show_push_branch
1111
1085
if directory is None:
1157
1131
_show_push_branch(br_from, revision_id, location, self.outf,
1158
1132
verbose=verbose, overwrite=overwrite, remember=remember,
1159
1133
stacked_on=stacked_on, create_prefix=create_prefix,
1160
use_existing_dir=use_existing_dir)
1134
use_existing_dir=use_existing_dir, no_tree=no_tree)
1163
1137
class cmd_branch(Command):
1177
1151
_see_also = ['checkout']
1178
1152
takes_args = ['from_location', 'to_location?']
1179
takes_options = ['revision', Option('hardlink',
1180
help='Hard-link working tree files where possible.'),
1153
takes_options = ['revision',
1154
Option('hardlink', help='Hard-link working tree files where possible.'),
1155
Option('files-from', type=str,
1156
help="Get file contents from this tree."),
1181
1157
Option('no-tree',
1182
1158
help="Create a branch without a working-tree."),
1183
1159
Option('switch',
1202
1178
def run(self, from_location, to_location=None, revision=None,
1203
1179
hardlink=False, stacked=False, standalone=False, no_tree=False,
1204
use_existing_dir=False, switch=False, bind=False):
1180
use_existing_dir=False, switch=False, bind=False,
1205
1182
from bzrlib import switch as _mod_switch
1206
1183
from bzrlib.tag import _merge_tags_if_possible
1207
1184
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1186
if not (hardlink or files_from):
1187
# accelerator_tree is usually slower because you have to read N
1188
# files (no readahead, lots of seeks, etc), but allow the user to
1189
# explicitly request it
1190
accelerator_tree = None
1191
if files_from is not None and files_from != from_location:
1192
accelerator_tree = WorkingTree.open(files_from)
1209
1193
revision = _get_one_revision('branch', revision)
1210
1194
self.add_cleanup(br_from.lock_read().unlock)
1211
1195
if revision is not None:
1318
1302
to_location = branch_location
1319
1303
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1320
1304
branch_location)
1305
if not (hardlink or files_from):
1306
# accelerator_tree is usually slower because you have to read N
1307
# files (no readahead, lots of seeks, etc), but allow the user to
1308
# explicitly request it
1309
accelerator_tree = None
1321
1310
revision = _get_one_revision('checkout', revision)
1322
if files_from is not None:
1311
if files_from is not None and files_from != branch_location:
1323
1312
accelerator_tree = WorkingTree.open(files_from)
1324
1313
if revision is not None:
1325
1314
revision_id = revision.as_revision_id(source)
1381
1370
If you want to discard your local changes, you can just do a
1382
1371
'bzr revert' instead of 'bzr commit' after the update.
1373
If you want to restore a file that has been removed locally, use
1374
'bzr revert' instead of 'bzr update'.
1384
1376
If the tree's branch is bound to a master branch, it will also update
1385
1377
the branch from the master.
1388
1380
_see_also = ['pull', 'working-trees', 'status-flags']
1389
1381
takes_args = ['dir?']
1390
takes_options = ['revision']
1382
takes_options = ['revision',
1384
help="Show base revision text in conflicts."),
1391
1386
aliases = ['up']
1393
def run(self, dir='.', revision=None):
1388
def run(self, dir='.', revision=None, show_base=None):
1394
1389
if revision is not None and len(revision) != 1:
1395
1390
raise errors.BzrCommandError(
1396
1391
"bzr update --revision takes exactly one revision")
1436
1431
change_reporter,
1437
1432
possible_transports=possible_transports,
1438
1433
revision=revision_id,
1435
show_base=show_base)
1440
1436
except errors.NoSuchRevision, e:
1441
1437
raise errors.BzrCommandError(
1442
1438
"branch has no revision %s\n"
1504
1500
class cmd_remove(Command):
1505
1501
__doc__ = """Remove files or directories.
1507
This makes bzr stop tracking changes to the specified files. bzr will delete
1508
them if they can easily be recovered using revert. If no options or
1509
parameters are given bzr will scan for files that are being tracked by bzr
1510
but missing in your tree and stop tracking them for you.
1503
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1504
delete them if they can easily be recovered using revert otherwise they
1505
will be backed up (adding an extention of the form .~#~). If no options or
1506
parameters are given Bazaar will scan for files that are being tracked by
1507
Bazaar but missing in your tree and stop tracking them for you.
1512
1509
takes_args = ['file*']
1513
1510
takes_options = ['verbose',
1515
1512
RegistryOption.from_kwargs('file-deletion-strategy',
1516
1513
'The file deletion mode to be used.',
1517
1514
title='Deletion Strategy', value_switches=True, enum_switch=False,
1518
safe='Only delete files if they can be'
1519
' safely recovered (default).',
1515
safe='Backup changed files (default).',
1520
1516
keep='Delete from bzr but leave the working copy.',
1517
no_backup='Don\'t backup changed files.',
1521
1518
force='Delete all the specified files, even if they can not be '
1522
'recovered and even if they are non-empty directories.')]
1519
'recovered and even if they are non-empty directories. '
1520
'(deprecated, use no-backup)')]
1523
1521
aliases = ['rm', 'del']
1524
1522
encoding_type = 'replace'
1526
1524
def run(self, file_list, verbose=False, new=False,
1527
1525
file_deletion_strategy='safe'):
1528
tree, file_list = tree_files(file_list)
1526
if file_deletion_strategy == 'force':
1527
note("(The --force option is deprecated, rather use --no-backup "
1529
file_deletion_strategy = 'no-backup'
1531
tree, file_list = WorkingTree.open_containing_paths(file_list)
1530
1533
if file_list is not None:
1531
1534
file_list = [f for f in file_list]
1551
1554
file_deletion_strategy = 'keep'
1552
1555
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1553
1556
keep_files=file_deletion_strategy=='keep',
1554
force=file_deletion_strategy=='force')
1557
force=(file_deletion_strategy=='no-backup'))
1557
1560
class cmd_file_id(Command):
1620
1623
_see_also = ['check']
1621
1624
takes_args = ['branch?']
1626
Option('canonicalize-chks',
1627
help='Make sure CHKs are in canonical form (repairs '
1623
def run(self, branch="."):
1632
def run(self, branch=".", canonicalize_chks=False):
1624
1633
from bzrlib.reconcile import reconcile
1625
1634
dir = bzrdir.BzrDir.open(branch)
1635
reconcile(dir, canonicalize_chks=canonicalize_chks)
1629
1638
class cmd_revision_history(Command):
1707
1716
Option('append-revisions-only',
1708
1717
help='Never change revnos or the existing log.'
1709
' Append revisions to it only.')
1718
' Append revisions to it only.'),
1720
'Create a branch without a working tree.')
1711
1722
def run(self, location=None, format=None, append_revisions_only=False,
1712
create_prefix=False):
1723
create_prefix=False, no_tree=False):
1713
1724
if format is None:
1714
1725
format = bzrdir.format_registry.make_bzrdir('default')
1715
1726
if location is None:
1738
1749
except errors.NotBranchError:
1739
1750
# really a NotBzrDir error...
1740
1751
create_branch = bzrdir.BzrDir.create_branch_convenience
1753
force_new_tree = False
1755
force_new_tree = None
1741
1756
branch = create_branch(to_transport.base, format=format,
1742
possible_transports=[to_transport])
1757
possible_transports=[to_transport],
1758
force_new_tree=force_new_tree)
1743
1759
a_bzrdir = branch.bzrdir
1745
1761
from bzrlib.transport.local import LocalTransport
1749
1765
raise errors.BranchExistsWithoutWorkingTree(location)
1750
1766
raise errors.AlreadyBranchError(location)
1751
1767
branch = a_bzrdir.create_branch()
1752
a_bzrdir.create_workingtree()
1769
a_bzrdir.create_workingtree()
1753
1770
if append_revisions_only:
1755
1772
branch.set_append_revisions_only(True)
1969
1990
old_branch, new_branch,
1970
1991
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1971
1992
file_list, revision, old, new, self.add_cleanup, apply_view=True)
1993
# GNU diff on Windows uses ANSI encoding for filenames
1994
path_encoding = osutils.get_diff_header_encoding()
1972
1995
return show_diff_trees(old_tree, new_tree, sys.stdout,
1973
1996
specific_files=specific_files,
1974
1997
external_diff_options=diff_options,
1975
1998
old_label=old_label, new_label=new_label,
1976
extra_trees=extra_trees, using=using,
1999
extra_trees=extra_trees,
2000
path_encoding=path_encoding,
1977
2002
format_cls=format)
1987
2012
# level of effort but possibly much less IO. (Or possibly not,
1988
2013
# if the directories are very large...)
1989
2014
_see_also = ['status', 'ls']
1990
takes_options = ['show-ids']
2015
takes_options = ['directory', 'show-ids']
1992
2017
@display_command
1993
def run(self, show_ids=False):
1994
tree = WorkingTree.open_containing(u'.')[0]
2018
def run(self, show_ids=False, directory=u'.'):
2019
tree = WorkingTree.open_containing(directory)[0]
1995
2020
self.add_cleanup(tree.lock_read().unlock)
1996
2021
old = tree.basis_tree()
1997
2022
self.add_cleanup(old.lock_read().unlock)
2012
2037
_see_also = ['status', 'ls']
2015
help='Write an ascii NUL (\\0) separator '
2016
'between files rather than a newline.')
2038
takes_options = ['directory', 'null']
2019
2040
@display_command
2020
def run(self, null=False):
2021
tree = WorkingTree.open_containing(u'.')[0]
2041
def run(self, null=False, directory=u'.'):
2042
tree = WorkingTree.open_containing(directory)[0]
2022
2043
td = tree.changes_from(tree.basis_tree())
2023
2044
for path, id, kind, text_modified, meta_modified in td.modified:
2035
2056
_see_also = ['status', 'ls']
2038
help='Write an ascii NUL (\\0) separator '
2039
'between files rather than a newline.')
2057
takes_options = ['directory', 'null']
2042
2059
@display_command
2043
def run(self, null=False):
2044
wt = WorkingTree.open_containing(u'.')[0]
2060
def run(self, null=False, directory=u'.'):
2061
wt = WorkingTree.open_containing(directory)[0]
2045
2062
self.add_cleanup(wt.lock_read().unlock)
2046
2063
basis = wt.basis_tree()
2047
2064
self.add_cleanup(basis.lock_read().unlock)
2053
2070
if inv.is_root(file_id) and len(basis_inv) == 0:
2055
2072
path = inv.id2path(file_id)
2056
if not os.access(osutils.abspath(path), os.F_OK):
2073
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2059
2076
self.outf.write(path + '\0')
2259
2276
help='Show just the specified revision.'
2260
2277
' See also "help revisionspec".'),
2279
RegistryOption('authors',
2280
'What names to list as authors - first, all or committer.',
2282
lazy_registry=('bzrlib.log', 'author_list_registry'),
2262
2284
Option('levels',
2263
2285
short_name='n',
2264
2286
help='Number of levels to display - 0 for all, 1 for flat.',
2382
2405
show_timezone=timezone,
2383
2406
delta_format=get_verbosity_level(),
2385
show_advice=levels is None)
2408
show_advice=levels is None,
2409
author_list_handler=authors)
2387
2411
# Choose the algorithm for doing the logging. It's annoying
2388
2412
# having multiple code paths like this but necessary until
2505
2529
help='Recurse into subdirectories.'),
2506
2530
Option('from-root',
2507
2531
help='Print paths relative to the root of the branch.'),
2508
Option('unknown', help='Print unknown files.'),
2532
Option('unknown', short_name='u',
2533
help='Print unknown files.'),
2509
2534
Option('versioned', help='Print versioned files.',
2510
2535
short_name='V'),
2511
Option('ignored', help='Print ignored files.'),
2513
help='Write an ascii NUL (\\0) separator '
2514
'between files rather than a newline.'),
2536
Option('ignored', short_name='i',
2537
help='Print ignored files.'),
2538
Option('kind', short_name='k',
2516
2539
help='List entries of a particular kind: file, directory, symlink.',
2520
2545
@display_command
2521
2546
def run(self, revision=None, verbose=False,
2522
2547
recursive=False, from_root=False,
2523
2548
unknown=False, versioned=False, ignored=False,
2524
null=False, kind=None, show_ids=False, path=None):
2549
null=False, kind=None, show_ids=False, path=None, directory=None):
2526
2551
if kind and kind not in ('file', 'directory', 'symlink'):
2527
2552
raise errors.BzrCommandError('invalid kind specified')
2539
2564
raise errors.BzrCommandError('cannot specify both --from-root'
2542
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2567
tree, branch, relpath = \
2568
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2545
2570
# Calculate the prefix to use
2616
2641
_see_also = ['ls']
2642
takes_options = ['directory']
2618
2644
@display_command
2620
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2645
def run(self, directory=u'.'):
2646
for f in WorkingTree.open_containing(directory)[0].unknowns():
2621
2647
self.outf.write(osutils.quotefn(f) + '\n')
2689
2715
_see_also = ['status', 'ignored', 'patterns']
2690
2716
takes_args = ['name_pattern*']
2717
takes_options = ['directory',
2692
2718
Option('default-rules',
2693
2719
help='Display the default ignore rules that bzr uses.')
2696
def run(self, name_pattern_list=None, default_rules=None):
2722
def run(self, name_pattern_list=None, default_rules=None,
2697
2724
from bzrlib import ignores
2698
2725
if default_rules is not None:
2699
2726
# dump the default rules and exit
2705
2732
"NAME_PATTERN or --default-rules.")
2706
2733
name_pattern_list = [globbing.normalize_pattern(p)
2707
2734
for p in name_pattern_list]
2736
for p in name_pattern_list:
2737
if not globbing.Globster.is_pattern_valid(p):
2738
bad_patterns += ('\n %s' % p)
2740
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2741
ui.ui_factory.show_error(msg)
2742
raise errors.InvalidPattern('')
2708
2743
for name_pattern in name_pattern_list:
2709
2744
if (name_pattern[0] == '/' or
2710
2745
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2711
2746
raise errors.BzrCommandError(
2712
2747
"NAME_PATTERN should not be an absolute path")
2713
tree, relpath = WorkingTree.open_containing(u'.')
2748
tree, relpath = WorkingTree.open_containing(directory)
2714
2749
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2715
2750
ignored = globbing.Globster(name_pattern_list)
2752
self.add_cleanup(tree.lock_read().unlock)
2718
2753
for entry in tree.list_files():
2720
2755
if id is not None:
2721
2756
filename = entry[0]
2722
2757
if ignored.match(filename):
2723
2758
matches.append(filename)
2725
2759
if len(matches) > 0:
2726
2760
self.outf.write("Warning: the following files are version controlled and"
2727
2761
" match your ignore pattern:\n%s"
2743
2777
encoding_type = 'replace'
2744
2778
_see_also = ['ignore', 'ls']
2779
takes_options = ['directory']
2746
2781
@display_command
2748
tree = WorkingTree.open_containing(u'.')[0]
2782
def run(self, directory=u'.'):
2783
tree = WorkingTree.open_containing(directory)[0]
2749
2784
self.add_cleanup(tree.lock_read().unlock)
2750
2785
for path, file_class, kind, file_id, entry in tree.list_files():
2751
2786
if file_class != 'I':
2765
2800
takes_args = ['revno']
2801
takes_options = ['directory']
2767
2803
@display_command
2768
def run(self, revno):
2804
def run(self, revno, directory=u'.'):
2770
2806
revno = int(revno)
2771
2807
except ValueError:
2772
2808
raise errors.BzrCommandError("not a valid revision-number: %r"
2774
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2810
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2775
2811
self.outf.write("%s\n" % revid)
2804
2840
================= =========================
2806
2842
takes_args = ['dest', 'branch_or_subdir?']
2843
takes_options = ['directory',
2808
2844
Option('format',
2809
2845
help="Type of file to export to.",
2819
2855
'revision in which it was changed.'),
2821
2857
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2822
root=None, filters=False, per_file_timestamps=False):
2858
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2823
2859
from bzrlib.export import export
2825
2861
if branch_or_subdir is None:
2826
tree = WorkingTree.open_containing(u'.')[0]
2862
tree = WorkingTree.open_containing(directory)[0]
2827
2863
b = tree.branch
2850
2886
_see_also = ['ls']
2887
takes_options = ['directory',
2852
2888
Option('name-from-revision', help='The path name in the old tree.'),
2853
2889
Option('filters', help='Apply content filters to display the '
2854
2890
'convenience form.'),
2860
2896
@display_command
2861
2897
def run(self, filename, revision=None, name_from_revision=False,
2898
filters=False, directory=None):
2863
2899
if revision is not None and len(revision) != 1:
2864
2900
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2865
2901
" one revision specifier")
2866
2902
tree, branch, relpath = \
2867
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2903
_open_directory_or_containing_tree_or_branch(filename, directory)
2868
2904
self.add_cleanup(branch.lock_read().unlock)
2869
2905
return self._run(tree, branch, relpath, filename, revision,
2870
2906
name_from_revision, filters)
3102
3138
properties = {}
3104
tree, selected_list = tree_files(selected_list)
3140
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3105
3141
if selected_list == ['']:
3106
3142
# workaround - commit of root of tree should be exactly the same
3107
3143
# as just default commit in that tree, and succeed even though
3142
3178
def get_message(commit_obj):
3143
3179
"""Callback to get commit message"""
3145
my_message = codecs.open(
3146
file, 'rt', osutils.get_user_encoding()).read()
3183
my_message = f.read().decode(osutils.get_user_encoding())
3147
3186
elif message is not None:
3148
3187
my_message = message
3178
3217
reporter=None, verbose=verbose, revprops=properties,
3179
3218
authors=author, timestamp=commit_stamp,
3180
3219
timezone=offset,
3181
exclude=safe_relpath_files(tree, exclude))
3220
exclude=tree.safe_relpath_files(exclude))
3182
3221
except PointlessCommit:
3183
3222
raise errors.BzrCommandError("No changes to commit."
3184
3223
" Use --unchanged to commit anyhow.")
3304
3343
bzr whoami "Frank Chu <fchu@example.com>"
3306
takes_options = [ Option('email',
3345
takes_options = [ 'directory',
3307
3347
help='Display email address only.'),
3308
3348
Option('branch',
3309
3349
help='Set identity for the current branch instead of '
3313
3353
encoding_type = 'replace'
3315
3355
@display_command
3316
def run(self, email=False, branch=False, name=None):
3356
def run(self, email=False, branch=False, name=None, directory=None):
3317
3357
if name is None:
3318
# use branch if we're inside one; otherwise global config
3320
c = Branch.open_containing('.')[0].get_config()
3321
except errors.NotBranchError:
3322
c = config.GlobalConfig()
3358
if directory is None:
3359
# use branch if we're inside one; otherwise global config
3361
c = Branch.open_containing(u'.')[0].get_config()
3362
except errors.NotBranchError:
3363
c = _mod_config.GlobalConfig()
3365
c = Branch.open(directory).get_config()
3324
3367
self.outf.write(c.user_email() + '\n')
3329
3372
# display a warning if an email address isn't included in the given name.
3331
config.extract_email_address(name)
3374
_mod_config.extract_email_address(name)
3332
3375
except errors.NoEmailInUsername, e:
3333
3376
warning('"%s" does not seem to contain an email address. '
3334
3377
'This is allowed, but not recommended.', name)
3336
3379
# use global config unless --branch given
3338
c = Branch.open_containing('.')[0].get_config()
3381
if directory is None:
3382
c = Branch.open_containing(u'.')[0].get_config()
3384
c = Branch.open(directory).get_config()
3340
c = config.GlobalConfig()
3386
c = _mod_config.GlobalConfig()
3341
3387
c.set_user_option('email', name)
3354
3400
_see_also = ['info']
3355
3401
takes_args = ['nickname?']
3356
def run(self, nickname=None):
3357
branch = Branch.open_containing(u'.')[0]
3402
takes_options = ['directory']
3403
def run(self, nickname=None, directory=u'.'):
3404
branch = Branch.open_containing(directory)[0]
3358
3405
if nickname is None:
3359
3406
self.printme(branch)
3409
3456
'bzr alias --remove expects an alias to remove.')
3410
3457
# If alias is not found, print something like:
3411
3458
# unalias: foo: not found
3412
c = config.GlobalConfig()
3459
c = _mod_config.GlobalConfig()
3413
3460
c.unset_alias(alias_name)
3415
3462
@display_command
3416
3463
def print_aliases(self):
3417
3464
"""Print out the defined aliases in a similar format to bash."""
3418
aliases = config.GlobalConfig().get_aliases()
3465
aliases = _mod_config.GlobalConfig().get_aliases()
3419
3466
for key, value in sorted(aliases.iteritems()):
3420
3467
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3432
3479
def set_alias(self, alias_name, alias_command):
3433
3480
"""Save the alias in the global config."""
3434
c = config.GlobalConfig()
3481
c = _mod_config.GlobalConfig()
3435
3482
c.set_alias(alias_name, alias_command)
3472
3519
If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
3473
3520
into a pdb postmortem session.
3522
The --coverage=DIRNAME global option produces a report with covered code
3476
3526
Run only tests relating to 'ignore'::
3510
3560
'throughout the test suite.',
3511
3561
type=get_transport_type),
3512
3562
Option('benchmark',
3513
help='Run the benchmarks rather than selftests.'),
3563
help='Run the benchmarks rather than selftests.',
3514
3565
Option('lsprof-timed',
3515
3566
help='Generate lsprof output for benchmarked'
3516
3567
' sections of code.'),
3517
3568
Option('lsprof-tests',
3518
3569
help='Generate lsprof output for each test.'),
3519
Option('cache-dir', type=str,
3520
help='Cache intermediate benchmark output in this '
3522
3570
Option('first',
3523
3571
help='Run all tests, but run specified tests first.',
3524
3572
short_name='f',
3559
3607
def run(self, testspecs_list=None, verbose=False, one=False,
3560
3608
transport=None, benchmark=None,
3561
lsprof_timed=None, cache_dir=None,
3562
3610
first=False, list_only=False,
3563
3611
randomize=None, exclude=None, strict=False,
3564
3612
load_list=None, debugflag=None, starting_with=None, subunit=False,
3565
3613
parallel=None, lsprof_tests=False):
3566
from bzrlib.tests import selftest
3567
import bzrlib.benchmarks as benchmarks
3568
from bzrlib.benchmarks import tree_creator
3570
# Make deprecation warnings visible, unless -Werror is set
3571
symbol_versioning.activate_deprecation_warnings(override=False)
3573
if cache_dir is not None:
3574
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3614
from bzrlib import tests
3575
3616
if testspecs_list is not None:
3576
3617
pattern = '|'.join(testspecs_list)
3585
3626
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3586
3627
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3587
3628
# stdout, which would corrupt the subunit stream.
3588
if sys.platform == "win32" and sys.stdout.fileno() >= 0:
3629
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3630
# following code can be deleted when it's sufficiently deployed
3631
# -- vila/mgz 20100514
3632
if (sys.platform == "win32"
3633
and getattr(sys.stdout, 'fileno', None) is not None):
3590
3635
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3592
3637
self.additional_selftest_args.setdefault(
3593
3638
'suite_decorators', []).append(parallel)
3595
test_suite_factory = benchmarks.test_suite
3596
# Unless user explicitly asks for quiet, be verbose in benchmarks
3597
verbose = not is_quiet()
3598
# TODO: should possibly lock the history file...
3599
benchfile = open(".perf_history", "at", buffering=1)
3600
self.add_cleanup(benchfile.close)
3602
test_suite_factory = None
3640
raise errors.BzrCommandError(
3641
"--benchmark is no longer supported from bzr 2.2; "
3642
"use bzr-usertest instead")
3643
test_suite_factory = None
3604
3644
selftest_kwargs = {"verbose": verbose,
3605
3645
"pattern": pattern,
3606
3646
"stop_on_failure": one,
3608
3648
"test_suite_factory": test_suite_factory,
3609
3649
"lsprof_timed": lsprof_timed,
3610
3650
"lsprof_tests": lsprof_tests,
3611
"bench_history": benchfile,
3612
3651
"matching_tests_first": first,
3613
3652
"list_only": list_only,
3614
3653
"random_seed": randomize,
3619
3658
"starting_with": starting_with
3621
3660
selftest_kwargs.update(self.additional_selftest_args)
3622
result = selftest(**selftest_kwargs)
3662
# Make deprecation warnings visible, unless -Werror is set
3663
cleanup = symbol_versioning.activate_deprecation_warnings(
3666
result = tests.selftest(**selftest_kwargs)
3623
3669
return int(not result)
3764
3810
' completely merged into the source, pull from the'
3765
3811
' source rather than merging. When this happens,'
3766
3812
' you do not need to commit the result.'),
3813
custom_help('directory',
3768
3814
help='Branch to merge into, '
3769
'rather than the one containing the working directory.',
3815
'rather than the one containing the working directory.'),
3773
3816
Option('preview', help='Instead of merging, show a diff of the'
3775
3818
Option('interactive', help='Select changes interactively.',
3875
3918
def _do_preview(self, merger):
3876
3919
from bzrlib.diff import show_diff_trees
3877
3920
result_tree = self._get_preview(merger)
3921
path_encoding = osutils.get_diff_header_encoding()
3878
3922
show_diff_trees(merger.this_tree, result_tree, self.outf,
3879
old_label='', new_label='')
3923
old_label='', new_label='',
3924
path_encoding=path_encoding)
3881
3926
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3882
3927
merger.change_reporter = change_reporter
4069
4114
from bzrlib.conflicts import restore
4070
4115
if merge_type is None:
4071
4116
merge_type = _mod_merge.Merge3Merger
4072
tree, file_list = tree_files(file_list)
4117
tree, file_list = WorkingTree.open_containing_paths(file_list)
4073
4118
self.add_cleanup(tree.lock_write().unlock)
4074
4119
parents = tree.get_parent_ids()
4075
4120
if len(parents) != 2:
4186
4231
def run(self, revision=None, no_backup=False, file_list=None,
4187
4232
forget_merges=None):
4188
tree, file_list = tree_files(file_list)
4233
tree, file_list = WorkingTree.open_containing_paths(file_list)
4189
4234
self.add_cleanup(tree.lock_tree_write().unlock)
4190
4235
if forget_merges:
4191
4236
tree.set_parent_ids(tree.get_parent_ids()[:1])
4281
4326
_see_also = ['merge', 'pull']
4282
4327
takes_args = ['other_branch?']
4283
4328
takes_options = [
4284
4330
Option('reverse', 'Reverse the order of revisions.'),
4285
4331
Option('mine-only',
4286
4332
'Display changes in the local branch only.'),
4308
4354
theirs_only=False,
4309
4355
log_format=None, long=False, short=False, line=False,
4310
4356
show_ids=False, verbose=False, this=False, other=False,
4311
include_merges=False, revision=None, my_revision=None):
4357
include_merges=False, revision=None, my_revision=None,
4312
4359
from bzrlib.missing import find_unmerged, iter_log_revisions
4313
4360
def message(s):
4314
4361
if not is_quiet():
4542
4589
Option('long', help='Show commit date in annotations.'),
4546
4594
encoding_type = 'exact'
4548
4596
@display_command
4549
4597
def run(self, filename, all=False, long=False, revision=None,
4598
show_ids=False, directory=None):
4551
4599
from bzrlib.annotate import annotate_file, annotate_file_tree
4552
4600
wt, branch, relpath = \
4553
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4601
_open_directory_or_containing_tree_or_branch(filename, directory)
4554
4602
if wt is not None:
4555
4603
self.add_cleanup(wt.lock_read().unlock)
4581
4629
hidden = True # is this right ?
4582
4630
takes_args = ['revision_id*']
4583
takes_options = ['revision']
4631
takes_options = ['directory', 'revision']
4585
def run(self, revision_id_list=None, revision=None):
4633
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4586
4634
if revision_id_list is not None and revision is not None:
4587
4635
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4588
4636
if revision_id_list is None and revision is None:
4589
4637
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4590
b = WorkingTree.open_containing(u'.')[0].branch
4638
b = WorkingTree.open_containing(directory)[0].branch
4591
4639
self.add_cleanup(b.lock_write().unlock)
4592
4640
return self._run(b, revision_id_list, revision)
4654
4702
_see_also = ['checkouts', 'unbind']
4655
4703
takes_args = ['location?']
4704
takes_options = ['directory']
4658
def run(self, location=None):
4659
b, relpath = Branch.open_containing(u'.')
4706
def run(self, location=None, directory=u'.'):
4707
b, relpath = Branch.open_containing(directory)
4660
4708
if location is None:
4662
4710
location = b.get_old_bound_location()
4690
4738
_see_also = ['checkouts', 'bind']
4691
4739
takes_args = []
4740
takes_options = ['directory']
4695
b, relpath = Branch.open_containing(u'.')
4742
def run(self, directory=u'.'):
4743
b, relpath = Branch.open_containing(directory)
4696
4744
if not b.unbind():
4697
4745
raise errors.BzrCommandError('Local branch is not bound')
4791
4839
self.outf.write('The above revision(s) will be removed.\n')
4794
if not ui.ui_factory.get_boolean('Are you sure'):
4795
self.outf.write('Canceled')
4842
if not ui.ui_factory.confirm_action(
4843
'Uncommit these revisions',
4844
'bzrlib.builtins.uncommit',
4846
self.outf.write('Canceled\n')
4798
4849
mutter('Uncommitting from {%s} to {%s}',
4806
4857
class cmd_break_lock(Command):
4807
__doc__ = """Break a dead lock on a repository, branch or working directory.
4858
__doc__ = """Break a dead lock.
4860
This command breaks a lock on a repository, branch, working directory or
4809
4863
CAUTION: Locks should only be broken when you are sure that the process
4810
4864
holding the lock has been stopped.
4817
4871
bzr break-lock bzr+ssh://example.com/bzr/foo
4872
bzr break-lock --conf ~/.bazaar
4819
4875
takes_args = ['location?']
4878
help='LOCATION is the directory where the config lock is.'),
4880
help='Do not ask for confirmation before breaking the lock.'),
4821
def run(self, location=None, show=False):
4883
def run(self, location=None, config=False, force=False):
4822
4884
if location is None:
4823
4885
location = u'.'
4824
control, relpath = bzrdir.BzrDir.open_containing(location)
4826
control.break_lock()
4827
except NotImplementedError:
4887
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
4889
{'bzrlib.lockdir.break': True})
4891
conf = _mod_config.LockableConfig(file_name=location)
4894
control, relpath = bzrdir.BzrDir.open_containing(location)
4896
control.break_lock()
4897
except NotImplementedError:
4831
4901
class cmd_wait_until_signalled(Command):
4860
4930
'result in a dynamically allocated port. The default port '
4861
4931
'depends on the protocol.',
4864
help='Serve contents of this directory.',
4933
custom_help('directory',
4934
help='Serve contents of this directory.'),
4866
4935
Option('allow-writes',
4867
4936
help='By default the server is a readonly server. Supplying '
4868
4937
'--allow-writes enables write access to the contents of '
4896
4965
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4897
4966
protocol=None):
4898
from bzrlib.transport import get_transport, transport_server_registry
4967
from bzrlib import transport
4899
4968
if directory is None:
4900
4969
directory = os.getcwd()
4901
4970
if protocol is None:
4902
protocol = transport_server_registry.get()
4971
protocol = transport.transport_server_registry.get()
4903
4972
host, port = self.get_host_and_port(port)
4904
4973
url = urlutils.local_path_to_url(directory)
4905
4974
if not allow_writes:
4906
4975
url = 'readonly+' + url
4907
transport = get_transport(url)
4908
protocol(transport, host, port, inet)
4976
t = transport.get_transport(url)
4977
protocol(t, host, port, inet)
4911
4980
class cmd_join(Command):
4917
4986
not part of it. (Such trees can be produced by "bzr split", but also by
4918
4987
running "bzr branch" with the target inside a tree.)
4920
The result is a combined tree, with the subtree no longer an independant
4989
The result is a combined tree, with the subtree no longer an independent
4921
4990
part. This is marked as a merge of the subtree into the containing tree,
4922
4991
and all history is preserved.
5022
5092
encoding_type = 'exact'
5024
5094
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5025
sign=False, revision=None, mail_to=None, message=None):
5095
sign=False, revision=None, mail_to=None, message=None,
5026
5097
from bzrlib.revision import ensure_null, NULL_REVISION
5027
5098
include_patch, include_bundle = {
5028
5099
'plain': (False, False),
5029
5100
'diff': (True, False),
5030
5101
'bundle': (True, True),
5032
branch = Branch.open('.')
5103
branch = Branch.open(directory)
5033
5104
stored_submit_branch = branch.get_submit_branch()
5034
5105
if submit_branch is None:
5035
5106
submit_branch = stored_submit_branch
5120
5191
given, in which case it is sent to a file.
5122
5193
Mail is sent using your preferred mail program. This should be transparent
5123
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5194
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5124
5195
If the preferred client can't be found (or used), your editor will be used.
5126
5197
To use a specific mail program, set the mail_client configuration option.
5297
5368
Option('delete',
5298
5369
help='Delete this tag rather than placing it.',
5301
help='Branch in which to place the tag.',
5371
custom_help('directory',
5372
help='Branch in which to place the tag.'),
5305
5373
Option('force',
5306
5374
help='Replace existing tags.',
5338
5406
if (not force) and branch.tags.has_tag(tag_name):
5339
5407
raise errors.TagAlreadyExists(tag_name)
5340
5408
branch.tags.set_tag(tag_name, revision_id)
5341
self.outf.write('Created tag %s.\n' % tag_name)
5409
note('Created tag %s.' % tag_name)
5344
5412
class cmd_tags(Command):
5350
5418
_see_also = ['tag']
5351
5419
takes_options = [
5353
help='Branch whose tags should be displayed.',
5420
custom_help('directory',
5421
help='Branch whose tags should be displayed.'),
5357
5422
RegistryOption.from_kwargs('sort',
5358
5423
'Sort tags by different criteria.', title='Sorting',
5359
alpha='Sort tags lexicographically (default).',
5424
natural='Sort numeric substrings as numbers:'
5425
' suitable for version numbers. (default)',
5426
alpha='Sort tags lexicographically.',
5360
5427
time='Sort tags chronologically.',
5384
5451
# only show revisions between revid1 and revid2 (inclusive)
5385
5452
tags = [(tag, revid) for tag, revid in tags if
5386
5453
graph.is_between(revid, revid1, revid2)]
5454
if sort == 'natural':
5455
def natural_sort_key(tag):
5456
return [f(s) for f,s in
5457
zip(itertools.cycle((unicode.lower,int)),
5458
re.split('([0-9]+)', tag[0]))]
5459
tags.sort(key=natural_sort_key)
5460
elif sort == 'alpha':
5389
5462
elif sort == 'time':
5390
5463
timestamps = {}
5531
5604
takes_args = ['to_location?']
5532
takes_options = [Option('force',
5605
takes_options = ['directory',
5533
5607
help='Switch even if local commits will be lost.'),
5535
5609
Option('create-branch', short_name='b',
5540
5614
def run(self, to_location=None, force=False, create_branch=False,
5615
revision=None, directory=u'.'):
5542
5616
from bzrlib import switch
5617
tree_location = directory
5544
5618
revision = _get_one_revision('switch', revision)
5545
5619
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5546
5620
if to_location is None:
5547
5621
if revision is None:
5548
5622
raise errors.BzrCommandError('You must supply either a'
5549
5623
' revision or a location')
5624
to_location = tree_location
5552
5626
branch = control_dir.open_branch()
5553
5627
had_explicit_nick = branch.get_config().has_explicit_nickname()
5691
tree, file_list = tree_files(file_list, apply_view=False)
5765
tree, file_list = WorkingTree.open_containing_paths(file_list,
5692
5767
current_view, view_dict = tree.views.get_view_info()
5693
5768
if name is None:
5694
5769
name = current_view
5842
5918
_see_also = ['unshelve']
5844
5920
def run(self, revision=None, all=False, file_list=None, message=None,
5845
writer=None, list=False, destroy=False):
5921
writer=None, list=False, destroy=False, directory=u'.'):
5847
5923
return self.run_for_list()
5848
5924
from bzrlib.shelf_ui import Shelver
5850
5926
writer = bzrlib.option.diff_writer_registry.get()
5852
5928
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5853
file_list, message, destroy=destroy)
5929
file_list, message, destroy=destroy, directory=directory)
5885
5961
takes_args = ['shelf_id?']
5886
5962
takes_options = [
5887
5964
RegistryOption.from_kwargs(
5888
5965
'action', help="The action to perform.",
5889
5966
enum_switch=False, value_switches=True,
5898
5975
_see_also = ['shelve']
5900
def run(self, shelf_id=None, action='apply'):
5977
def run(self, shelf_id=None, action='apply', directory=u'.'):
5901
5978
from bzrlib.shelf_ui import Unshelver
5902
unshelver = Unshelver.from_args(shelf_id, action)
5979
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5904
5981
unshelver.run()
5922
5999
To check what clean-tree will do, use --dry-run.
5924
takes_options = [Option('ignored', help='Delete all ignored files.'),
6001
takes_options = ['directory',
6002
Option('ignored', help='Delete all ignored files.'),
5925
6003
Option('detritus', help='Delete conflict files, merge'
5926
6004
' backups, and failed selftest dirs.'),
5927
6005
Option('unknown',
5930
6008
' deleting them.'),
5931
6009
Option('force', help='Do not prompt before deleting.')]
5932
6010
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6011
force=False, directory=u'.'):
5934
6012
from bzrlib.clean_tree import clean_tree
5935
6013
if not (unknown or ignored or detritus):
5939
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5940
dry_run=dry_run, no_prompt=force)
6017
clean_tree(directory, unknown=unknown, ignored=ignored,
6018
detritus=detritus, dry_run=dry_run, no_prompt=force)
5943
6021
class cmd_reference(Command):