76
75
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
79
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
80
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
82
return internal_tree_files(file_list, default_branch, canonicalize,
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]))
86
88
def tree_files_for_add(file_list):
151
153
# XXX: Bad function name; should possibly also be a class method of
152
154
# WorkingTree rather than a function.
153
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
154
155
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
155
156
apply_view=True):
156
157
"""Convert command-line paths to a WorkingTree and relative paths.
158
Deprecated: use WorkingTree.open_containing_paths instead.
160
159
This is typically used for command-line processors that take one or
161
160
more filenames, and infer the workingtree that contains them.
173
172
:return: workingtree, [relative_paths]
175
return WorkingTree.open_containing_paths(
176
file_list, default_directory='.',
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)
181
223
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)
201
235
# TODO: Make sure no commands unconditionally use the working directory as a
202
236
# branch. If a filename argument is used, the first of them should be used to
203
237
# specify the branch. (Perhaps this can be factored out into some kind of
252
286
To skip the display of pending merge information altogether, use
253
287
the no-pending option or specify a file/directory.
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'.
289
If a revision argument is given, the status is calculated against
290
that revision, or between two revisions if two are provided.
263
293
# TODO: --no-recurse, --recurse options
285
315
raise errors.BzrCommandError('bzr status --revision takes exactly'
286
316
' one or two revision specifiers')
288
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
318
tree, relfile_list = tree_files(file_list)
289
319
# Avoid asking for specific files when that is not needed.
290
320
if relfile_list == ['']:
291
321
relfile_list = None
323
353
self.outf.write(revtext.decode('utf-8'))
326
def run(self, revision_id=None, revision=None, directory=u'.'):
356
def run(self, revision_id=None, revision=None):
327
357
if revision_id is not None and revision is not None:
328
358
raise errors.BzrCommandError('You can only supply one of'
329
359
' revision_id or --revision')
330
360
if revision_id is None and revision is None:
331
361
raise errors.BzrCommandError('You must supply either'
332
362
' --revision or a revision_id')
333
b = WorkingTree.open_containing(directory)[0].branch
363
b = WorkingTree.open_containing(u'.')[0].branch
335
365
revisions = b.repository.revisions
336
366
if revisions is None:
474
504
if (working.has_changes()):
475
505
raise errors.UncommittedChanges(working)
476
if working.get_shelf_manager().last_shelf() is not None:
477
raise errors.ShelvedChanges(working)
479
507
if working.user_url != working.branch.user_url:
480
508
raise errors.BzrCommandError("You cannot remove the working tree"
502
530
wt = WorkingTree.open_containing(location)[0]
503
self.add_cleanup(wt.lock_read().unlock)
504
532
except (errors.NoWorkingTree, errors.NotLocalUrl):
505
533
raise errors.NoWorkingTree(location)
534
self.add_cleanup(wt.unlock)
506
535
revid = wt.last_revision()
508
537
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
511
540
revno = ".".join(str(n) for n in revno_t)
513
542
b = Branch.open_containing(location)[0]
514
self.add_cleanup(b.lock_read().unlock)
544
self.add_cleanup(b.unlock)
515
545
revno = b.revno()
516
546
self.cleanup_now()
517
547
self.outf.write(str(revno) + '\n')
524
554
takes_args = ['revision_info*']
525
555
takes_options = [
527
custom_help('directory',
528
558
help='Branch to examine, '
529
'rather than the one containing the working directory.'),
559
'rather than the one containing the working directory.',
530
563
Option('tree', help='Show revno of working tree'),
538
571
wt = WorkingTree.open_containing(directory)[0]
540
self.add_cleanup(wt.lock_read().unlock)
574
self.add_cleanup(wt.unlock)
541
575
except (errors.NoWorkingTree, errors.NotLocalUrl):
543
577
b = Branch.open_containing(directory)[0]
544
self.add_cleanup(b.lock_read().unlock)
579
self.add_cleanup(b.unlock)
545
580
revision_ids = []
546
581
if revision is not None:
547
582
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
646
681
should_print=(not is_quiet()))
649
self.add_cleanup(base_tree.lock_read().unlock)
684
base_tree.lock_read()
685
self.add_cleanup(base_tree.unlock)
650
686
tree, file_list = tree_files_for_add(file_list)
651
687
added, ignored = tree.smart_add(file_list, not
652
688
no_recurse, action=action, save=not dry_run)
723
759
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
725
761
revision = _get_one_revision('inventory', revision)
726
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
727
self.add_cleanup(work_tree.lock_read().unlock)
762
work_tree, file_list = tree_files(file_list)
763
work_tree.lock_read()
764
self.add_cleanup(work_tree.unlock)
728
765
if revision is not None:
729
766
tree = revision.as_tree(work_tree.branch)
731
768
extra_trees = [work_tree]
732
self.add_cleanup(tree.lock_read().unlock)
770
self.add_cleanup(tree.unlock)
795
833
if len(names_list) < 2:
796
834
raise errors.BzrCommandError("missing file argument")
797
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
798
self.add_cleanup(tree.lock_tree_write().unlock)
835
tree, rel_names = tree_files(names_list, canonicalize=False)
836
tree.lock_tree_write()
837
self.add_cleanup(tree.unlock)
799
838
self._run(tree, names_list, rel_names, after)
801
840
def run_auto(self, names_list, after, dry_run):
806
845
raise errors.BzrCommandError('--after cannot be specified with'
808
work_tree, file_list = WorkingTree.open_containing_paths(
809
names_list, default_directory='.')
810
self.add_cleanup(work_tree.lock_tree_write().unlock)
847
work_tree, file_list = tree_files(names_list, default_branch='.')
848
work_tree.lock_tree_write()
849
self.add_cleanup(work_tree.unlock)
811
850
rename_map.RenameMap.guess_renames(work_tree, dry_run)
813
852
def _run(self, tree, names_list, rel_names, after):
921
960
takes_options = ['remember', 'overwrite', 'revision',
922
961
custom_help('verbose',
923
962
help='Show logs of pulled revisions.'),
924
custom_help('directory',
925
964
help='Branch to pull into, '
926
'rather than the one containing the working directory.'),
965
'rather than the one containing the working directory.',
928
970
help="Perform a local pull in a bound "
929
971
"branch. Local pulls are not applied to "
930
972
"the master branch."
933
help="Show base revision text in conflicts.")
935
975
takes_args = ['location?']
936
976
encoding_type = 'replace'
938
978
def run(self, location=None, remember=False, overwrite=False,
939
979
revision=None, verbose=False,
940
directory=None, local=False,
980
directory=None, local=False):
942
981
# FIXME: too much stuff is in the command class
943
982
revision_id = None
948
987
tree_to = WorkingTree.open_containing(directory)[0]
949
988
branch_to = tree_to.branch
950
self.add_cleanup(tree_to.lock_write().unlock)
990
self.add_cleanup(tree_to.unlock)
951
991
except errors.NoWorkingTree:
953
993
branch_to = Branch.open_containing(directory)[0]
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.")
994
branch_to.lock_write()
995
self.add_cleanup(branch_to.unlock)
959
997
if local and not branch_to.get_bound_location():
960
998
raise errors.LocalRequiresBoundBranch()
992
1030
branch_from = Branch.open(location,
993
1031
possible_transports=possible_transports)
994
self.add_cleanup(branch_from.lock_read().unlock)
1032
branch_from.lock_read()
1033
self.add_cleanup(branch_from.unlock)
996
1035
if branch_to.get_parent() is None or remember:
997
1036
branch_to.set_parent(branch_from.base)
1006
1045
view_info=view_info)
1007
1046
result = tree_to.pull(
1008
1047
branch_from, overwrite, revision_id, change_reporter,
1009
possible_transports=possible_transports, local=local,
1010
show_base=show_base)
1048
possible_transports=possible_transports, local=local)
1012
1050
result = branch_to.pull(
1013
1051
branch_from, overwrite, revision_id, local=local)
1050
1088
Option('create-prefix',
1051
1089
help='Create the path leading up to the branch '
1052
1090
'if it does not already exist.'),
1053
custom_help('directory',
1054
1092
help='Branch to push from, '
1055
'rather than the one containing the working directory.'),
1093
'rather than the one containing the working directory.',
1056
1097
Option('use-existing-dir',
1057
1098
help='By default push will fail if the target'
1058
1099
' directory exists, but does not already'
1069
1110
Option('strict',
1070
1111
help='Refuse to push if there are uncommitted changes in'
1071
1112
' the working tree, --no-strict disables the check.'),
1073
help="Don't populate the working tree, even for protocols"
1074
" that support it."),
1076
1114
takes_args = ['location?']
1077
1115
encoding_type = 'replace'
1079
1117
def run(self, location=None, remember=False, overwrite=False,
1080
1118
create_prefix=False, verbose=False, revision=None,
1081
1119
use_existing_dir=False, directory=None, stacked_on=None,
1082
stacked=False, strict=None, no_tree=False):
1120
stacked=False, strict=None):
1083
1121
from bzrlib.push import _show_push_branch
1085
1123
if directory is None:
1131
1169
_show_push_branch(br_from, revision_id, location, self.outf,
1132
1170
verbose=verbose, overwrite=overwrite, remember=remember,
1133
1171
stacked_on=stacked_on, create_prefix=create_prefix,
1134
use_existing_dir=use_existing_dir, no_tree=no_tree)
1172
use_existing_dir=use_existing_dir)
1137
1175
class cmd_branch(Command):
1151
1189
_see_also = ['checkout']
1152
1190
takes_args = ['from_location', 'to_location?']
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."),
1191
takes_options = ['revision', Option('hardlink',
1192
help='Hard-link working tree files where possible.'),
1157
1193
Option('no-tree',
1158
1194
help="Create a branch without a working-tree."),
1159
1195
Option('switch',
1178
1214
def run(self, from_location, to_location=None, revision=None,
1179
1215
hardlink=False, stacked=False, standalone=False, no_tree=False,
1180
use_existing_dir=False, switch=False, bind=False,
1216
use_existing_dir=False, switch=False, bind=False):
1182
1217
from bzrlib import switch as _mod_switch
1183
1218
from bzrlib.tag import _merge_tags_if_possible
1184
1219
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)
1193
1221
revision = _get_one_revision('branch', revision)
1194
self.add_cleanup(br_from.lock_read().unlock)
1223
self.add_cleanup(br_from.unlock)
1195
1224
if revision is not None:
1196
1225
revision_id = revision.as_revision_id(br_from)
1302
1331
to_location = branch_location
1303
1332
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1304
1333
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
1310
1334
revision = _get_one_revision('checkout', revision)
1311
if files_from is not None and files_from != branch_location:
1335
if files_from is not None:
1312
1336
accelerator_tree = WorkingTree.open(files_from)
1313
1337
if revision is not None:
1314
1338
revision_id = revision.as_revision_id(source)
1342
1366
@display_command
1343
1367
def run(self, dir=u'.'):
1344
1368
tree = WorkingTree.open_containing(dir)[0]
1345
self.add_cleanup(tree.lock_read().unlock)
1370
self.add_cleanup(tree.unlock)
1346
1371
new_inv = tree.inventory
1347
1372
old_tree = tree.basis_tree()
1348
self.add_cleanup(old_tree.lock_read().unlock)
1373
old_tree.lock_read()
1374
self.add_cleanup(old_tree.unlock)
1349
1375
old_inv = old_tree.inventory
1351
1377
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1370
1396
If you want to discard your local changes, you can just do a
1371
1397
'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'.
1376
1399
If the tree's branch is bound to a master branch, it will also update
1377
1400
the branch from the master.
1380
1403
_see_also = ['pull', 'working-trees', 'status-flags']
1381
1404
takes_args = ['dir?']
1382
takes_options = ['revision',
1384
help="Show base revision text in conflicts."),
1405
takes_options = ['revision']
1386
1406
aliases = ['up']
1388
def run(self, dir='.', revision=None, show_base=None):
1408
def run(self, dir='.', revision=None):
1389
1409
if revision is not None and len(revision) != 1:
1390
1410
raise errors.BzrCommandError(
1391
1411
"bzr update --revision takes exactly one revision")
1395
1415
master = branch.get_master_branch(
1396
1416
possible_transports=possible_transports)
1397
1417
if master is not None:
1398
1419
branch_location = master.base
1421
tree.lock_tree_write()
1401
1422
branch_location = tree.branch.base
1402
tree.lock_tree_write()
1403
1423
self.add_cleanup(tree.unlock)
1404
1424
# get rid of the final '/' and be ready for display
1405
1425
branch_location = urlutils.unescape_for_display(
1431
1451
change_reporter,
1432
1452
possible_transports=possible_transports,
1433
1453
revision=revision_id,
1435
show_base=show_base)
1436
1455
except errors.NoSuchRevision, e:
1437
1456
raise errors.BzrCommandError(
1438
1457
"branch has no revision %s\n"
1500
1519
class cmd_remove(Command):
1501
1520
__doc__ = """Remove files or directories.
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.
1522
This makes bzr stop tracking changes to the specified files. bzr will delete
1523
them if they can easily be recovered using revert. If no options or
1524
parameters are given bzr will scan for files that are being tracked by bzr
1525
but missing in your tree and stop tracking them for you.
1509
1527
takes_args = ['file*']
1510
1528
takes_options = ['verbose',
1512
1530
RegistryOption.from_kwargs('file-deletion-strategy',
1513
1531
'The file deletion mode to be used.',
1514
1532
title='Deletion Strategy', value_switches=True, enum_switch=False,
1515
safe='Backup changed files (default).',
1533
safe='Only delete files if they can be'
1534
' safely recovered (default).',
1516
1535
keep='Delete from bzr but leave the working copy.',
1517
no_backup='Don\'t backup changed files.',
1518
1536
force='Delete all the specified files, even if they can not be '
1519
'recovered and even if they are non-empty directories. '
1520
'(deprecated, use no-backup)')]
1537
'recovered and even if they are non-empty directories.')]
1521
1538
aliases = ['rm', 'del']
1522
1539
encoding_type = 'replace'
1524
1541
def run(self, file_list, verbose=False, new=False,
1525
1542
file_deletion_strategy='safe'):
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)
1543
tree, file_list = tree_files(file_list)
1533
1545
if file_list is not None:
1534
1546
file_list = [f for f in file_list]
1536
self.add_cleanup(tree.lock_write().unlock)
1549
self.add_cleanup(tree.unlock)
1537
1550
# Heuristics should probably all move into tree.remove_smart or
1554
1567
file_deletion_strategy = 'keep'
1555
1568
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1556
1569
keep_files=file_deletion_strategy=='keep',
1557
force=(file_deletion_strategy=='no-backup'))
1570
force=file_deletion_strategy=='force')
1560
1573
class cmd_file_id(Command):
1623
1636
_see_also = ['check']
1624
1637
takes_args = ['branch?']
1626
Option('canonicalize-chks',
1627
help='Make sure CHKs are in canonical form (repairs '
1632
def run(self, branch=".", canonicalize_chks=False):
1639
def run(self, branch="."):
1633
1640
from bzrlib.reconcile import reconcile
1634
1641
dir = bzrdir.BzrDir.open(branch)
1635
reconcile(dir, canonicalize_chks=canonicalize_chks)
1638
1645
class cmd_revision_history(Command):
1716
1723
Option('append-revisions-only',
1717
1724
help='Never change revnos or the existing log.'
1718
' Append revisions to it only.'),
1720
'Create a branch without a working tree.')
1725
' Append revisions to it only.')
1722
1727
def run(self, location=None, format=None, append_revisions_only=False,
1723
create_prefix=False, no_tree=False):
1728
create_prefix=False):
1724
1729
if format is None:
1725
1730
format = bzrdir.format_registry.make_bzrdir('default')
1726
1731
if location is None:
1749
1754
except errors.NotBranchError:
1750
1755
# really a NotBzrDir error...
1751
1756
create_branch = bzrdir.BzrDir.create_branch_convenience
1753
force_new_tree = False
1755
force_new_tree = None
1756
1757
branch = create_branch(to_transport.base, format=format,
1757
possible_transports=[to_transport],
1758
force_new_tree=force_new_tree)
1758
possible_transports=[to_transport])
1759
1759
a_bzrdir = branch.bzrdir
1761
1761
from bzrlib.transport.local import LocalTransport
1765
1765
raise errors.BranchExistsWithoutWorkingTree(location)
1766
1766
raise errors.AlreadyBranchError(location)
1767
1767
branch = a_bzrdir.create_branch()
1769
a_bzrdir.create_workingtree()
1768
a_bzrdir.create_workingtree()
1770
1769
if append_revisions_only:
1772
1771
branch.set_append_revisions_only(True)
1866
1865
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1867
1866
produces patches suitable for "patch -p1".
1869
Note that when using the -r argument with a range of revisions, the
1870
differences are computed between the two specified revisions. That
1871
is, the command does not show the changes introduced by the first
1872
revision in the range. This differs from the interpretation of
1873
revision ranges used by "bzr log" which includes the first revision
1878
1870
2 - unrepresentable changes
1911
1899
bzr diff -r<chosen_parent>..X
1913
The changes between the current revision and the previous revision
1914
(equivalent to -c-1 and -r-2..-1)
1901
The changes introduced by revision 2 (equivalent to -r1..2)::
1918
1905
Show just the differences for file NEWS::
2002
1985
old_branch, new_branch,
2003
1986
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2004
1987
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2005
# GNU diff on Windows uses ANSI encoding for filenames
2006
path_encoding = osutils.get_diff_header_encoding()
2007
1988
return show_diff_trees(old_tree, new_tree, sys.stdout,
2008
1989
specific_files=specific_files,
2009
1990
external_diff_options=diff_options,
2010
1991
old_label=old_label, new_label=new_label,
2011
extra_trees=extra_trees,
2012
path_encoding=path_encoding,
1992
extra_trees=extra_trees, using=using,
2014
1993
format_cls=format)
2024
2003
# level of effort but possibly much less IO. (Or possibly not,
2025
2004
# if the directories are very large...)
2026
2005
_see_also = ['status', 'ls']
2027
takes_options = ['directory', 'show-ids']
2006
takes_options = ['show-ids']
2029
2008
@display_command
2030
def run(self, show_ids=False, directory=u'.'):
2031
tree = WorkingTree.open_containing(directory)[0]
2032
self.add_cleanup(tree.lock_read().unlock)
2009
def run(self, show_ids=False):
2010
tree = WorkingTree.open_containing(u'.')[0]
2012
self.add_cleanup(tree.unlock)
2033
2013
old = tree.basis_tree()
2034
self.add_cleanup(old.lock_read().unlock)
2015
self.add_cleanup(old.unlock)
2035
2016
for path, ie in old.inventory.iter_entries():
2036
2017
if not tree.has_id(ie.file_id):
2037
2018
self.outf.write(path)
2049
2030
_see_also = ['status', 'ls']
2050
takes_options = ['directory', 'null']
2033
help='Write an ascii NUL (\\0) separator '
2034
'between files rather than a newline.')
2052
2037
@display_command
2053
def run(self, null=False, directory=u'.'):
2054
tree = WorkingTree.open_containing(directory)[0]
2038
def run(self, null=False):
2039
tree = WorkingTree.open_containing(u'.')[0]
2055
2040
td = tree.changes_from(tree.basis_tree())
2056
2041
for path, id, kind, text_modified, meta_modified in td.modified:
2068
2053
_see_also = ['status', 'ls']
2069
takes_options = ['directory', 'null']
2056
help='Write an ascii NUL (\\0) separator '
2057
'between files rather than a newline.')
2071
2060
@display_command
2072
def run(self, null=False, directory=u'.'):
2073
wt = WorkingTree.open_containing(directory)[0]
2074
self.add_cleanup(wt.lock_read().unlock)
2061
def run(self, null=False):
2062
wt = WorkingTree.open_containing(u'.')[0]
2064
self.add_cleanup(wt.unlock)
2075
2065
basis = wt.basis_tree()
2076
self.add_cleanup(basis.lock_read().unlock)
2067
self.add_cleanup(basis.unlock)
2077
2068
basis_inv = basis.inventory
2078
2069
inv = wt.inventory
2079
2070
for file_id in inv:
2082
2073
if inv.is_root(file_id) and len(basis_inv) == 0:
2084
2075
path = inv.id2path(file_id)
2085
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2076
if not os.access(osutils.abspath(path), os.F_OK):
2088
2079
self.outf.write(path + '\0')
2288
2279
help='Show just the specified revision.'
2289
2280
' See also "help revisionspec".'),
2291
RegistryOption('authors',
2292
'What names to list as authors - first, all or committer.',
2294
lazy_registry=('bzrlib.log', 'author_list_registry'),
2296
2282
Option('levels',
2297
2283
short_name='n',
2298
2284
help='Number of levels to display - 0 for all, 1 for flat.',
2368
2353
# find the file ids to log and check for directory filtering
2369
2354
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2370
revision, file_list, self.add_cleanup)
2355
revision, file_list)
2356
self.add_cleanup(b.unlock)
2371
2357
for relpath, file_id, kind in file_info_list:
2372
2358
if file_id is None:
2373
2359
raise errors.BzrCommandError(
2392
2378
dir, relpath = bzrdir.BzrDir.open_containing(location)
2393
2379
b = dir.open_branch()
2394
self.add_cleanup(b.lock_read().unlock)
2381
self.add_cleanup(b.unlock)
2395
2382
rev1, rev2 = _get_revision_range(revision, b, self.name())
2397
2384
# Decide on the type of delta & diff filtering to use
2417
2404
show_timezone=timezone,
2418
2405
delta_format=get_verbosity_level(),
2420
show_advice=levels is None,
2421
author_list_handler=authors)
2407
show_advice=levels is None)
2423
2409
# Choose the algorithm for doing the logging. It's annoying
2424
2410
# having multiple code paths like this but necessary until
2522
2508
tree, relpath = WorkingTree.open_containing(filename)
2523
2509
file_id = tree.path2id(relpath)
2524
2510
b = tree.branch
2525
self.add_cleanup(b.lock_read().unlock)
2512
self.add_cleanup(b.unlock)
2526
2513
touching_revs = log.find_touching_revisions(b, file_id)
2527
2514
for revno, revision_id, what in touching_revs:
2528
2515
self.outf.write("%6d %s\n" % (revno, what))
2541
2528
help='Recurse into subdirectories.'),
2542
2529
Option('from-root',
2543
2530
help='Print paths relative to the root of the branch.'),
2544
Option('unknown', short_name='u',
2545
help='Print unknown files.'),
2531
Option('unknown', help='Print unknown files.'),
2546
2532
Option('versioned', help='Print versioned files.',
2547
2533
short_name='V'),
2548
Option('ignored', short_name='i',
2549
help='Print ignored files.'),
2550
Option('kind', short_name='k',
2534
Option('ignored', help='Print ignored files.'),
2536
help='Write an ascii NUL (\\0) separator '
2537
'between files rather than a newline.'),
2551
2539
help='List entries of a particular kind: file, directory, symlink.',
2557
2543
@display_command
2558
2544
def run(self, revision=None, verbose=False,
2559
2545
recursive=False, from_root=False,
2560
2546
unknown=False, versioned=False, ignored=False,
2561
null=False, kind=None, show_ids=False, path=None, directory=None):
2547
null=False, kind=None, show_ids=False, path=None):
2563
2549
if kind and kind not in ('file', 'directory', 'symlink'):
2564
2550
raise errors.BzrCommandError('invalid kind specified')
2576
2562
raise errors.BzrCommandError('cannot specify both --from-root'
2579
tree, branch, relpath = \
2580
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2565
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2582
2568
# Calculate the prefix to use
2598
2584
view_str = views.view_display_str(view_files)
2599
2585
note("Ignoring files outside view. View is %s" % view_str)
2601
self.add_cleanup(tree.lock_read().unlock)
2588
self.add_cleanup(tree.unlock)
2602
2589
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2603
2590
from_dir=relpath, recursive=recursive):
2604
2591
# Apply additional masking
2653
2640
_see_also = ['ls']
2654
takes_options = ['directory']
2656
2642
@display_command
2657
def run(self, directory=u'.'):
2658
for f in WorkingTree.open_containing(directory)[0].unknowns():
2644
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2659
2645
self.outf.write(osutils.quotefn(f) + '\n')
2688
2674
Patterns prefixed with '!!' act as regular ignore patterns, but have
2689
2675
precedence over the '!' exception patterns.
2693
* Ignore patterns containing shell wildcards must be quoted from
2696
* Ignore patterns starting with "#" act as comments in the ignore file.
2697
To ignore patterns that begin with that character, use the "RE:" prefix.
2677
Note: ignore patterns containing shell wildcards must be quoted from
2700
2681
Ignore the top level Makefile::
2736
2713
_see_also = ['status', 'ignored', 'patterns']
2737
2714
takes_args = ['name_pattern*']
2738
takes_options = ['directory',
2739
2716
Option('default-rules',
2740
2717
help='Display the default ignore rules that bzr uses.')
2743
def run(self, name_pattern_list=None, default_rules=None,
2720
def run(self, name_pattern_list=None, default_rules=None):
2745
2721
from bzrlib import ignores
2746
2722
if default_rules is not None:
2747
2723
# dump the default rules and exit
2753
2729
"NAME_PATTERN or --default-rules.")
2754
2730
name_pattern_list = [globbing.normalize_pattern(p)
2755
2731
for p in name_pattern_list]
2757
for p in name_pattern_list:
2758
if not globbing.Globster.is_pattern_valid(p):
2759
bad_patterns += ('\n %s' % p)
2761
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2762
ui.ui_factory.show_error(msg)
2763
raise errors.InvalidPattern('')
2764
2732
for name_pattern in name_pattern_list:
2765
2733
if (name_pattern[0] == '/' or
2766
2734
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2767
2735
raise errors.BzrCommandError(
2768
2736
"NAME_PATTERN should not be an absolute path")
2769
tree, relpath = WorkingTree.open_containing(directory)
2737
tree, relpath = WorkingTree.open_containing(u'.')
2770
2738
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2771
2739
ignored = globbing.Globster(name_pattern_list)
2773
self.add_cleanup(tree.lock_read().unlock)
2774
2742
for entry in tree.list_files():
2776
2744
if id is not None:
2777
2745
filename = entry[0]
2778
2746
if ignored.match(filename):
2779
2747
matches.append(filename)
2780
2749
if len(matches) > 0:
2781
2750
self.outf.write("Warning: the following files are version controlled and"
2782
2751
" match your ignore pattern:\n%s"
2798
2767
encoding_type = 'replace'
2799
2768
_see_also = ['ignore', 'ls']
2800
takes_options = ['directory']
2802
2770
@display_command
2803
def run(self, directory=u'.'):
2804
tree = WorkingTree.open_containing(directory)[0]
2805
self.add_cleanup(tree.lock_read().unlock)
2772
tree = WorkingTree.open_containing(u'.')[0]
2774
self.add_cleanup(tree.unlock)
2806
2775
for path, file_class, kind, file_id, entry in tree.list_files():
2807
2776
if file_class != 'I':
2821
2790
takes_args = ['revno']
2822
takes_options = ['directory']
2824
2792
@display_command
2825
def run(self, revno, directory=u'.'):
2793
def run(self, revno):
2827
2795
revno = int(revno)
2828
2796
except ValueError:
2829
2797
raise errors.BzrCommandError("not a valid revision-number: %r"
2831
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2799
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2832
2800
self.outf.write("%s\n" % revid)
2861
2829
================= =========================
2863
2831
takes_args = ['dest', 'branch_or_subdir?']
2864
takes_options = ['directory',
2865
2833
Option('format',
2866
2834
help="Type of file to export to.",
2876
2844
'revision in which it was changed.'),
2878
2846
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2879
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2847
root=None, filters=False, per_file_timestamps=False):
2880
2848
from bzrlib.export import export
2882
2850
if branch_or_subdir is None:
2883
tree = WorkingTree.open_containing(directory)[0]
2851
tree = WorkingTree.open_containing(u'.')[0]
2884
2852
b = tree.branch
2907
2875
_see_also = ['ls']
2908
takes_options = ['directory',
2909
2877
Option('name-from-revision', help='The path name in the old tree.'),
2910
2878
Option('filters', help='Apply content filters to display the '
2911
2879
'convenience form.'),
2917
2885
@display_command
2918
2886
def run(self, filename, revision=None, name_from_revision=False,
2919
filters=False, directory=None):
2920
2888
if revision is not None and len(revision) != 1:
2921
2889
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2922
2890
" one revision specifier")
2923
2891
tree, branch, relpath = \
2924
_open_directory_or_containing_tree_or_branch(filename, directory)
2925
self.add_cleanup(branch.lock_read().unlock)
2892
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2894
self.add_cleanup(branch.unlock)
2926
2895
return self._run(tree, branch, relpath, filename, revision,
2927
2896
name_from_revision, filters)
2931
2900
if tree is None:
2932
2901
tree = b.basis_tree()
2933
2902
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2934
self.add_cleanup(rev_tree.lock_read().unlock)
2903
rev_tree.lock_read()
2904
self.add_cleanup(rev_tree.unlock)
2936
2906
old_file_id = rev_tree.path2id(relpath)
3159
3129
properties = {}
3161
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3131
tree, selected_list = tree_files(selected_list)
3162
3132
if selected_list == ['']:
3163
3133
# workaround - commit of root of tree should be exactly the same
3164
3134
# as just default commit in that tree, and succeed even though
3199
3169
def get_message(commit_obj):
3200
3170
"""Callback to get commit message"""
3204
my_message = f.read().decode(osutils.get_user_encoding())
3172
my_message = codecs.open(
3173
file, 'rt', osutils.get_user_encoding()).read()
3207
3174
elif message is not None:
3208
3175
my_message = message
3238
3205
reporter=None, verbose=verbose, revprops=properties,
3239
3206
authors=author, timestamp=commit_stamp,
3240
3207
timezone=offset,
3241
exclude=tree.safe_relpath_files(exclude))
3208
exclude=safe_relpath_files(tree, exclude))
3242
3209
except PointlessCommit:
3243
3210
raise errors.BzrCommandError("No changes to commit."
3244
3211
" Use --unchanged to commit anyhow.")
3364
3331
bzr whoami "Frank Chu <fchu@example.com>"
3366
takes_options = [ 'directory',
3333
takes_options = [ Option('email',
3368
3334
help='Display email address only.'),
3369
3335
Option('branch',
3370
3336
help='Set identity for the current branch instead of '
3374
3340
encoding_type = 'replace'
3376
3342
@display_command
3377
def run(self, email=False, branch=False, name=None, directory=None):
3343
def run(self, email=False, branch=False, name=None):
3378
3344
if name is None:
3379
if directory is None:
3380
# use branch if we're inside one; otherwise global config
3382
c = Branch.open_containing(u'.')[0].get_config()
3383
except errors.NotBranchError:
3384
c = _mod_config.GlobalConfig()
3386
c = Branch.open(directory).get_config()
3345
# use branch if we're inside one; otherwise global config
3347
c = Branch.open_containing('.')[0].get_config()
3348
except errors.NotBranchError:
3349
c = config.GlobalConfig()
3388
3351
self.outf.write(c.user_email() + '\n')
3393
3356
# display a warning if an email address isn't included in the given name.
3395
_mod_config.extract_email_address(name)
3358
config.extract_email_address(name)
3396
3359
except errors.NoEmailInUsername, e:
3397
3360
warning('"%s" does not seem to contain an email address. '
3398
3361
'This is allowed, but not recommended.', name)
3400
3363
# use global config unless --branch given
3402
if directory is None:
3403
c = Branch.open_containing(u'.')[0].get_config()
3405
c = Branch.open(directory).get_config()
3365
c = Branch.open_containing('.')[0].get_config()
3407
c = _mod_config.GlobalConfig()
3367
c = config.GlobalConfig()
3408
3368
c.set_user_option('email', name)
3421
3381
_see_also = ['info']
3422
3382
takes_args = ['nickname?']
3423
takes_options = ['directory']
3424
def run(self, nickname=None, directory=u'.'):
3425
branch = Branch.open_containing(directory)[0]
3383
def run(self, nickname=None):
3384
branch = Branch.open_containing(u'.')[0]
3426
3385
if nickname is None:
3427
3386
self.printme(branch)
3477
3436
'bzr alias --remove expects an alias to remove.')
3478
3437
# If alias is not found, print something like:
3479
3438
# unalias: foo: not found
3480
c = _mod_config.GlobalConfig()
3439
c = config.GlobalConfig()
3481
3440
c.unset_alias(alias_name)
3483
3442
@display_command
3484
3443
def print_aliases(self):
3485
3444
"""Print out the defined aliases in a similar format to bash."""
3486
aliases = _mod_config.GlobalConfig().get_aliases()
3445
aliases = config.GlobalConfig().get_aliases()
3487
3446
for key, value in sorted(aliases.iteritems()):
3488
3447
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3500
3459
def set_alias(self, alias_name, alias_command):
3501
3460
"""Save the alias in the global config."""
3502
c = _mod_config.GlobalConfig()
3461
c = config.GlobalConfig()
3503
3462
c.set_alias(alias_name, alias_command)
3540
3499
If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
3541
3500
into a pdb postmortem session.
3543
The --coverage=DIRNAME global option produces a report with covered code
3547
3503
Run only tests relating to 'ignore'::
3581
3537
'throughout the test suite.',
3582
3538
type=get_transport_type),
3583
3539
Option('benchmark',
3584
help='Run the benchmarks rather than selftests.',
3540
help='Run the benchmarks rather than selftests.'),
3586
3541
Option('lsprof-timed',
3587
3542
help='Generate lsprof output for benchmarked'
3588
3543
' sections of code.'),
3589
3544
Option('lsprof-tests',
3590
3545
help='Generate lsprof output for each test.'),
3546
Option('cache-dir', type=str,
3547
help='Cache intermediate benchmark output in this '
3591
3549
Option('first',
3592
3550
help='Run all tests, but run specified tests first.',
3593
3551
short_name='f',
3628
3586
def run(self, testspecs_list=None, verbose=False, one=False,
3629
3587
transport=None, benchmark=None,
3588
lsprof_timed=None, cache_dir=None,
3631
3589
first=False, list_only=False,
3632
3590
randomize=None, exclude=None, strict=False,
3633
3591
load_list=None, debugflag=None, starting_with=None, subunit=False,
3634
3592
parallel=None, lsprof_tests=False):
3635
from bzrlib import tests
3593
from bzrlib.tests import selftest
3594
import bzrlib.benchmarks as benchmarks
3595
from bzrlib.benchmarks import tree_creator
3597
# Make deprecation warnings visible, unless -Werror is set
3598
symbol_versioning.activate_deprecation_warnings(override=False)
3600
if cache_dir is not None:
3601
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3637
3602
if testspecs_list is not None:
3638
3603
pattern = '|'.join(testspecs_list)
3647
3612
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3648
3613
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3649
3614
# stdout, which would corrupt the subunit stream.
3650
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3651
# following code can be deleted when it's sufficiently deployed
3652
# -- vila/mgz 20100514
3653
if (sys.platform == "win32"
3654
and getattr(sys.stdout, 'fileno', None) is not None):
3615
if sys.platform == "win32" and sys.stdout.fileno() >= 0:
3656
3617
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3658
3619
self.additional_selftest_args.setdefault(
3659
3620
'suite_decorators', []).append(parallel)
3661
raise errors.BzrCommandError(
3662
"--benchmark is no longer supported from bzr 2.2; "
3663
"use bzr-usertest instead")
3664
test_suite_factory = None
3622
test_suite_factory = benchmarks.test_suite
3623
# Unless user explicitly asks for quiet, be verbose in benchmarks
3624
verbose = not is_quiet()
3625
# TODO: should possibly lock the history file...
3626
benchfile = open(".perf_history", "at", buffering=1)
3627
self.add_cleanup(benchfile.close)
3629
test_suite_factory = None
3665
3631
selftest_kwargs = {"verbose": verbose,
3666
3632
"pattern": pattern,
3667
3633
"stop_on_failure": one,
3669
3635
"test_suite_factory": test_suite_factory,
3670
3636
"lsprof_timed": lsprof_timed,
3671
3637
"lsprof_tests": lsprof_tests,
3638
"bench_history": benchfile,
3672
3639
"matching_tests_first": first,
3673
3640
"list_only": list_only,
3674
3641
"random_seed": randomize,
3679
3646
"starting_with": starting_with
3681
3648
selftest_kwargs.update(self.additional_selftest_args)
3683
# Make deprecation warnings visible, unless -Werror is set
3684
cleanup = symbol_versioning.activate_deprecation_warnings(
3687
result = tests.selftest(**selftest_kwargs)
3649
result = selftest(**selftest_kwargs)
3690
3650
return int(not result)
3731
3691
branch1 = Branch.open_containing(branch)[0]
3732
3692
branch2 = Branch.open_containing(other)[0]
3733
self.add_cleanup(branch1.lock_read().unlock)
3734
self.add_cleanup(branch2.lock_read().unlock)
3694
self.add_cleanup(branch1.unlock)
3696
self.add_cleanup(branch2.unlock)
3735
3697
last1 = ensure_null(branch1.last_revision())
3736
3698
last2 = ensure_null(branch2.last_revision())
3831
3793
' completely merged into the source, pull from the'
3832
3794
' source rather than merging. When this happens,'
3833
3795
' you do not need to commit the result.'),
3834
custom_help('directory',
3835
3797
help='Branch to merge into, '
3836
'rather than the one containing the working directory.'),
3798
'rather than the one containing the working directory.',
3837
3802
Option('preview', help='Instead of merging, show a diff of the'
3839
3804
Option('interactive', help='Select changes interactively.',
3872
3837
unversioned_filter=tree.is_ignored, view_info=view_info)
3873
3838
pb = ui.ui_factory.nested_progress_bar()
3874
3839
self.add_cleanup(pb.finished)
3875
self.add_cleanup(tree.lock_write().unlock)
3841
self.add_cleanup(tree.unlock)
3876
3842
if location is not None:
3878
3844
mergeable = bundle.read_mergeable_from_url(location,
3939
3905
def _do_preview(self, merger):
3940
3906
from bzrlib.diff import show_diff_trees
3941
3907
result_tree = self._get_preview(merger)
3942
path_encoding = osutils.get_diff_header_encoding()
3943
3908
show_diff_trees(merger.this_tree, result_tree, self.outf,
3944
old_label='', new_label='',
3945
path_encoding=path_encoding)
3909
old_label='', new_label='')
3947
3911
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3948
3912
merger.change_reporter = change_reporter
4135
4099
from bzrlib.conflicts import restore
4136
4100
if merge_type is None:
4137
4101
merge_type = _mod_merge.Merge3Merger
4138
tree, file_list = WorkingTree.open_containing_paths(file_list)
4139
self.add_cleanup(tree.lock_write().unlock)
4102
tree, file_list = tree_files(file_list)
4104
self.add_cleanup(tree.unlock)
4140
4105
parents = tree.get_parent_ids()
4141
4106
if len(parents) != 2:
4142
4107
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4252
4217
def run(self, revision=None, no_backup=False, file_list=None,
4253
4218
forget_merges=None):
4254
tree, file_list = WorkingTree.open_containing_paths(file_list)
4255
self.add_cleanup(tree.lock_tree_write().unlock)
4219
tree, file_list = tree_files(file_list)
4220
tree.lock_tree_write()
4221
self.add_cleanup(tree.unlock)
4256
4222
if forget_merges:
4257
4223
tree.set_parent_ids(tree.get_parent_ids()[:1])
4347
4313
_see_also = ['merge', 'pull']
4348
4314
takes_args = ['other_branch?']
4349
4315
takes_options = [
4351
4316
Option('reverse', 'Reverse the order of revisions.'),
4352
4317
Option('mine-only',
4353
4318
'Display changes in the local branch only.'),
4375
4340
theirs_only=False,
4376
4341
log_format=None, long=False, short=False, line=False,
4377
4342
show_ids=False, verbose=False, this=False, other=False,
4378
include_merges=False, revision=None, my_revision=None,
4343
include_merges=False, revision=None, my_revision=None):
4380
4344
from bzrlib.missing import find_unmerged, iter_log_revisions
4381
4345
def message(s):
4382
4346
if not is_quiet():
4395
4359
elif theirs_only:
4396
4360
restrict = 'remote'
4398
local_branch = Branch.open_containing(directory)[0]
4399
self.add_cleanup(local_branch.lock_read().unlock)
4362
local_branch = Branch.open_containing(u".")[0]
4363
local_branch.lock_read()
4364
self.add_cleanup(local_branch.unlock)
4401
4366
parent = local_branch.get_parent()
4402
4367
if other_branch is None:
4413
4378
if remote_branch.base == local_branch.base:
4414
4379
remote_branch = local_branch
4416
self.add_cleanup(remote_branch.lock_read().unlock)
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4418
4384
local_revid_range = _revision_range_to_revid_range(
4419
4385
_get_revision_range(my_revision, local_branch,
4474
4440
message("Branches are up to date.\n")
4475
4441
self.cleanup_now()
4476
4442
if not status_code and parent is None and other_branch is not None:
4477
self.add_cleanup(local_branch.lock_write().unlock)
4443
local_branch.lock_write()
4444
self.add_cleanup(local_branch.unlock)
4478
4445
# handle race conditions - a parent might be set while we run.
4479
4446
if local_branch.get_parent() is None:
4480
4447
local_branch.set_parent(remote_branch.base)
4610
4578
Option('long', help='Show commit date in annotations.'),
4615
4582
encoding_type = 'exact'
4617
4584
@display_command
4618
4585
def run(self, filename, all=False, long=False, revision=None,
4619
show_ids=False, directory=None):
4620
4587
from bzrlib.annotate import annotate_file, annotate_file_tree
4621
4588
wt, branch, relpath = \
4622
_open_directory_or_containing_tree_or_branch(filename, directory)
4589
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4623
4590
if wt is not None:
4624
self.add_cleanup(wt.lock_read().unlock)
4592
self.add_cleanup(wt.unlock)
4626
self.add_cleanup(branch.lock_read().unlock)
4595
self.add_cleanup(branch.unlock)
4627
4596
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4628
self.add_cleanup(tree.lock_read().unlock)
4598
self.add_cleanup(tree.unlock)
4629
4599
if wt is not None:
4630
4600
file_id = wt.path2id(relpath)
4650
4620
hidden = True # is this right ?
4651
4621
takes_args = ['revision_id*']
4652
takes_options = ['directory', 'revision']
4622
takes_options = ['revision']
4654
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4624
def run(self, revision_id_list=None, revision=None):
4655
4625
if revision_id_list is not None and revision is not None:
4656
4626
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4657
4627
if revision_id_list is None and revision is None:
4658
4628
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4659
b = WorkingTree.open_containing(directory)[0].branch
4660
self.add_cleanup(b.lock_write().unlock)
4629
b = WorkingTree.open_containing(u'.')[0].branch
4631
self.add_cleanup(b.unlock)
4661
4632
return self._run(b, revision_id_list, revision)
4663
4634
def _run(self, b, revision_id_list, revision):
4723
4694
_see_also = ['checkouts', 'unbind']
4724
4695
takes_args = ['location?']
4725
takes_options = ['directory']
4727
def run(self, location=None, directory=u'.'):
4728
b, relpath = Branch.open_containing(directory)
4698
def run(self, location=None):
4699
b, relpath = Branch.open_containing(u'.')
4729
4700
if location is None:
4731
4702
location = b.get_old_bound_location()
4759
4730
_see_also = ['checkouts', 'bind']
4760
4731
takes_args = []
4761
takes_options = ['directory']
4763
def run(self, directory=u'.'):
4764
b, relpath = Branch.open_containing(directory)
4735
b, relpath = Branch.open_containing(u'.')
4765
4736
if not b.unbind():
4766
4737
raise errors.BzrCommandError('Local branch is not bound')
4813
4784
b = control.open_branch()
4815
4786
if tree is not None:
4816
self.add_cleanup(tree.lock_write().unlock)
4788
self.add_cleanup(tree.unlock)
4818
self.add_cleanup(b.lock_write().unlock)
4791
self.add_cleanup(b.unlock)
4819
4792
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4821
4794
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4860
4833
self.outf.write('The above revision(s) will be removed.\n')
4863
if not ui.ui_factory.confirm_action(
4864
'Uncommit these revisions',
4865
'bzrlib.builtins.uncommit',
4867
self.outf.write('Canceled\n')
4836
if not ui.ui_factory.get_boolean('Are you sure'):
4837
self.outf.write('Canceled')
4870
4840
mutter('Uncommitting from {%s} to {%s}',
4878
4848
class cmd_break_lock(Command):
4879
__doc__ = """Break a dead lock.
4881
This command breaks a lock on a repository, branch, working directory or
4849
__doc__ = """Break a dead lock on a repository, branch or working directory.
4884
4851
CAUTION: Locks should only be broken when you are sure that the process
4885
4852
holding the lock has been stopped.
4892
4859
bzr break-lock bzr+ssh://example.com/bzr/foo
4893
bzr break-lock --conf ~/.bazaar
4896
4861
takes_args = ['location?']
4899
help='LOCATION is the directory where the config lock is.'),
4901
help='Do not ask for confirmation before breaking the lock.'),
4904
def run(self, location=None, config=False, force=False):
4863
def run(self, location=None, show=False):
4905
4864
if location is None:
4906
4865
location = u'.'
4908
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
4910
{'bzrlib.lockdir.break': True})
4912
conf = _mod_config.LockableConfig(file_name=location)
4915
control, relpath = bzrdir.BzrDir.open_containing(location)
4917
control.break_lock()
4918
except NotImplementedError:
4866
control, relpath = bzrdir.BzrDir.open_containing(location)
4868
control.break_lock()
4869
except NotImplementedError:
4922
4873
class cmd_wait_until_signalled(Command):
4951
4902
'result in a dynamically allocated port. The default port '
4952
4903
'depends on the protocol.',
4954
custom_help('directory',
4955
help='Serve contents of this directory.'),
4906
help='Serve contents of this directory.',
4956
4908
Option('allow-writes',
4957
4909
help='By default the server is a readonly server. Supplying '
4958
4910
'--allow-writes enables write access to the contents of '
4986
4938
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4987
4939
protocol=None):
4988
from bzrlib import transport
4940
from bzrlib.transport import get_transport, transport_server_registry
4989
4941
if directory is None:
4990
4942
directory = os.getcwd()
4991
4943
if protocol is None:
4992
protocol = transport.transport_server_registry.get()
4944
protocol = transport_server_registry.get()
4993
4945
host, port = self.get_host_and_port(port)
4994
4946
url = urlutils.local_path_to_url(directory)
4995
4947
if not allow_writes:
4996
4948
url = 'readonly+' + url
4997
t = transport.get_transport(url)
4998
protocol(t, host, port, inet)
4949
transport = get_transport(url)
4950
protocol(transport, host, port, inet)
5001
4953
class cmd_join(Command):
5007
4959
not part of it. (Such trees can be produced by "bzr split", but also by
5008
4960
running "bzr branch" with the target inside a tree.)
5010
The result is a combined tree, with the subtree no longer an independent
4962
The result is a combined tree, with the subtree no longer an independant
5011
4963
part. This is marked as a merge of the subtree into the containing tree,
5012
4964
and all history is preserved.
5113
5064
encoding_type = 'exact'
5115
5066
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5116
sign=False, revision=None, mail_to=None, message=None,
5067
sign=False, revision=None, mail_to=None, message=None):
5118
5068
from bzrlib.revision import ensure_null, NULL_REVISION
5119
5069
include_patch, include_bundle = {
5120
5070
'plain': (False, False),
5121
5071
'diff': (True, False),
5122
5072
'bundle': (True, True),
5124
branch = Branch.open(directory)
5074
branch = Branch.open('.')
5125
5075
stored_submit_branch = branch.get_submit_branch()
5126
5076
if submit_branch is None:
5127
5077
submit_branch = stored_submit_branch
5212
5162
given, in which case it is sent to a file.
5214
5164
Mail is sent using your preferred mail program. This should be transparent
5215
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5165
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5216
5166
If the preferred client can't be found (or used), your editor will be used.
5218
5168
To use a specific mail program, set the mail_client configuration option.
5389
5339
Option('delete',
5390
5340
help='Delete this tag rather than placing it.',
5392
custom_help('directory',
5393
help='Branch in which to place the tag.'),
5343
help='Branch in which to place the tag.',
5394
5347
Option('force',
5395
5348
help='Replace existing tags.',
5406
5359
branch, relpath = Branch.open_containing(directory)
5407
self.add_cleanup(branch.lock_write().unlock)
5361
self.add_cleanup(branch.unlock)
5409
5363
if tag_name is None:
5410
5364
raise errors.BzrCommandError("No tag specified to delete.")
5411
5365
branch.tags.delete_tag(tag_name)
5412
note('Deleted tag %s.' % tag_name)
5366
self.outf.write('Deleted tag %s.\n' % tag_name)
5415
5369
if len(revision) != 1:
5427
5381
if (not force) and branch.tags.has_tag(tag_name):
5428
5382
raise errors.TagAlreadyExists(tag_name)
5429
5383
branch.tags.set_tag(tag_name, revision_id)
5430
note('Created tag %s.' % tag_name)
5384
self.outf.write('Created tag %s.\n' % tag_name)
5433
5387
class cmd_tags(Command):
5439
5393
_see_also = ['tag']
5440
5394
takes_options = [
5441
custom_help('directory',
5442
help='Branch whose tags should be displayed.'),
5396
help='Branch whose tags should be displayed.',
5443
5400
RegistryOption.from_kwargs('sort',
5444
5401
'Sort tags by different criteria.', title='Sorting',
5445
natural='Sort numeric substrings as numbers:'
5446
' suitable for version numbers. (default)',
5447
alpha='Sort tags lexicographically.',
5402
alpha='Sort tags lexicographically (default).',
5448
5403
time='Sort tags chronologically.',
5467
self.add_cleanup(branch.lock_read().unlock)
5423
self.add_cleanup(branch.unlock)
5469
5425
graph = branch.repository.get_graph()
5470
5426
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5472
5428
# only show revisions between revid1 and revid2 (inclusive)
5473
5429
tags = [(tag, revid) for tag, revid in tags if
5474
5430
graph.is_between(revid, revid1, revid2)]
5475
if sort == 'natural':
5476
def natural_sort_key(tag):
5477
return [f(s) for f,s in
5478
zip(itertools.cycle((unicode.lower,int)),
5479
re.split('([0-9]+)', tag[0]))]
5480
tags.sort(key=natural_sort_key)
5481
elif sort == 'alpha':
5483
5433
elif sort == 'time':
5484
5434
timestamps = {}
5625
5575
takes_args = ['to_location?']
5626
takes_options = ['directory',
5576
takes_options = [Option('force',
5628
5577
help='Switch even if local commits will be lost.'),
5630
5579
Option('create-branch', short_name='b',
5635
5584
def run(self, to_location=None, force=False, create_branch=False,
5636
revision=None, directory=u'.'):
5637
5586
from bzrlib import switch
5638
tree_location = directory
5639
5588
revision = _get_one_revision('switch', revision)
5640
5589
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5641
5590
if to_location is None:
5642
5591
if revision is None:
5643
5592
raise errors.BzrCommandError('You must supply either a'
5644
5593
' revision or a location')
5645
to_location = tree_location
5647
5596
branch = control_dir.open_branch()
5648
5597
had_explicit_nick = branch.get_config().has_explicit_nickname()
5786
tree, file_list = WorkingTree.open_containing_paths(file_list,
5735
tree, file_list = tree_files(file_list, apply_view=False)
5788
5736
current_view, view_dict = tree.views.get_view_info()
5789
5737
if name is None:
5790
5738
name = current_view
5920
5868
You can put multiple items on the shelf, and by default, 'unshelve' will
5921
5869
restore the most recently shelved changes.
5923
For complicated changes, it is possible to edit the changes in a separate
5924
editor program to decide what the file remaining in the working copy
5925
should look like. To do this, add the configuration option
5927
change_editor = PROGRAM @new_path @old_path
5929
where @new_path is replaced with the path of the new version of the
5930
file and @old_path is replaced with the path of the old version of
5931
the file. The PROGRAM should save the new file with the desired
5932
contents of the file in the working tree.
5936
5872
takes_args = ['file*']
5938
5874
takes_options = [
5941
5876
Option('all', help='Shelve all changes.'),
5948
5883
Option('destroy',
5949
5884
help='Destroy removed changes instead of shelving them.'),
5951
_see_also = ['unshelve', 'configuration']
5886
_see_also = ['unshelve']
5953
5888
def run(self, revision=None, all=False, file_list=None, message=None,
5954
writer=None, list=False, destroy=False, directory=u'.'):
5889
writer=None, list=False, destroy=False):
5956
5891
return self.run_for_list()
5957
5892
from bzrlib.shelf_ui import Shelver
5959
5894
writer = bzrlib.option.diff_writer_registry.get()
5961
5896
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5962
file_list, message, destroy=destroy, directory=directory)
5897
file_list, message, destroy=destroy)
5970
5905
def run_for_list(self):
5971
5906
tree = WorkingTree.open_containing('.')[0]
5972
self.add_cleanup(tree.lock_read().unlock)
5908
self.add_cleanup(tree.unlock)
5973
5909
manager = tree.get_shelf_manager()
5974
5910
shelves = manager.active_shelves()
5975
5911
if len(shelves) == 0:
5994
5930
takes_args = ['shelf_id?']
5995
5931
takes_options = [
5997
5932
RegistryOption.from_kwargs(
5998
5933
'action', help="The action to perform.",
5999
5934
enum_switch=False, value_switches=True,
6008
5943
_see_also = ['shelve']
6010
def run(self, shelf_id=None, action='apply', directory=u'.'):
5945
def run(self, shelf_id=None, action='apply'):
6011
5946
from bzrlib.shelf_ui import Unshelver
6012
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5947
unshelver = Unshelver.from_args(shelf_id, action)
6014
5949
unshelver.run()
6032
5967
To check what clean-tree will do, use --dry-run.
6034
takes_options = ['directory',
6035
Option('ignored', help='Delete all ignored files.'),
5969
takes_options = [Option('ignored', help='Delete all ignored files.'),
6036
5970
Option('detritus', help='Delete conflict files, merge'
6037
5971
' backups, and failed selftest dirs.'),
6038
5972
Option('unknown',
6041
5975
' deleting them.'),
6042
5976
Option('force', help='Do not prompt before deleting.')]
6043
5977
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6044
force=False, directory=u'.'):
6045
5979
from bzrlib.clean_tree import clean_tree
6046
5980
if not (unknown or ignored or detritus):
6050
clean_tree(directory, unknown=unknown, ignored=ignored,
6051
detritus=detritus, dry_run=dry_run, no_prompt=force)
5984
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5985
dry_run=dry_run, no_prompt=force)
6054
5988
class cmd_reference(Command):
6103
6037
# be only called once.
6104
6038
for (name, aliases, module_name) in [
6105
6039
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6106
('cmd_config', [], 'bzrlib.config'),
6107
6040
('cmd_dpush', [], 'bzrlib.foreign'),
6108
6041
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6109
6042
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6110
6043
('cmd_conflicts', [], 'bzrlib.conflicts'),
6111
6044
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6112
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6114
6046
builtin_command_registry.register_lazy(name, aliases, module_name)