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
4028
3992
if ((remember or tree.branch.get_submit_branch() is None) and
4029
3993
user_location is not None):
4030
3994
tree.branch.set_submit_branch(other_branch.base)
4031
# Merge tags (but don't set them in the master branch yet, the user
4032
# might revert this merge). Commit will propagate them.
4033
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3995
_merge_tags_if_possible(other_branch, tree.branch)
4034
3996
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
4035
3997
other_revision_id, base_revision_id, other_branch, base_branch)
4036
3998
if other_path != '':
4137
4099
from bzrlib.conflicts import restore
4138
4100
if merge_type is None:
4139
4101
merge_type = _mod_merge.Merge3Merger
4140
tree, file_list = WorkingTree.open_containing_paths(file_list)
4141
self.add_cleanup(tree.lock_write().unlock)
4102
tree, file_list = tree_files(file_list)
4104
self.add_cleanup(tree.unlock)
4142
4105
parents = tree.get_parent_ids()
4143
4106
if len(parents) != 2:
4144
4107
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4254
4217
def run(self, revision=None, no_backup=False, file_list=None,
4255
4218
forget_merges=None):
4256
tree, file_list = WorkingTree.open_containing_paths(file_list)
4257
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)
4258
4222
if forget_merges:
4259
4223
tree.set_parent_ids(tree.get_parent_ids()[:1])
4349
4313
_see_also = ['merge', 'pull']
4350
4314
takes_args = ['other_branch?']
4351
4315
takes_options = [
4353
4316
Option('reverse', 'Reverse the order of revisions.'),
4354
4317
Option('mine-only',
4355
4318
'Display changes in the local branch only.'),
4377
4340
theirs_only=False,
4378
4341
log_format=None, long=False, short=False, line=False,
4379
4342
show_ids=False, verbose=False, this=False, other=False,
4380
include_merges=False, revision=None, my_revision=None,
4343
include_merges=False, revision=None, my_revision=None):
4382
4344
from bzrlib.missing import find_unmerged, iter_log_revisions
4383
4345
def message(s):
4384
4346
if not is_quiet():
4397
4359
elif theirs_only:
4398
4360
restrict = 'remote'
4400
local_branch = Branch.open_containing(directory)[0]
4401
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)
4403
4366
parent = local_branch.get_parent()
4404
4367
if other_branch is None:
4415
4378
if remote_branch.base == local_branch.base:
4416
4379
remote_branch = local_branch
4418
self.add_cleanup(remote_branch.lock_read().unlock)
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4420
4384
local_revid_range = _revision_range_to_revid_range(
4421
4385
_get_revision_range(my_revision, local_branch,
4476
4440
message("Branches are up to date.\n")
4477
4441
self.cleanup_now()
4478
4442
if not status_code and parent is None and other_branch is not None:
4479
self.add_cleanup(local_branch.lock_write().unlock)
4443
local_branch.lock_write()
4444
self.add_cleanup(local_branch.unlock)
4480
4445
# handle race conditions - a parent might be set while we run.
4481
4446
if local_branch.get_parent() is None:
4482
4447
local_branch.set_parent(remote_branch.base)
4612
4578
Option('long', help='Show commit date in annotations.'),
4617
4582
encoding_type = 'exact'
4619
4584
@display_command
4620
4585
def run(self, filename, all=False, long=False, revision=None,
4621
show_ids=False, directory=None):
4622
4587
from bzrlib.annotate import annotate_file, annotate_file_tree
4623
4588
wt, branch, relpath = \
4624
_open_directory_or_containing_tree_or_branch(filename, directory)
4589
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4625
4590
if wt is not None:
4626
self.add_cleanup(wt.lock_read().unlock)
4592
self.add_cleanup(wt.unlock)
4628
self.add_cleanup(branch.lock_read().unlock)
4595
self.add_cleanup(branch.unlock)
4629
4596
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4630
self.add_cleanup(tree.lock_read().unlock)
4598
self.add_cleanup(tree.unlock)
4631
4599
if wt is not None:
4632
4600
file_id = wt.path2id(relpath)
4652
4620
hidden = True # is this right ?
4653
4621
takes_args = ['revision_id*']
4654
takes_options = ['directory', 'revision']
4622
takes_options = ['revision']
4656
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4624
def run(self, revision_id_list=None, revision=None):
4657
4625
if revision_id_list is not None and revision is not None:
4658
4626
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4659
4627
if revision_id_list is None and revision is None:
4660
4628
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4661
b = WorkingTree.open_containing(directory)[0].branch
4662
self.add_cleanup(b.lock_write().unlock)
4629
b = WorkingTree.open_containing(u'.')[0].branch
4631
self.add_cleanup(b.unlock)
4663
4632
return self._run(b, revision_id_list, revision)
4665
4634
def _run(self, b, revision_id_list, revision):
4725
4694
_see_also = ['checkouts', 'unbind']
4726
4695
takes_args = ['location?']
4727
takes_options = ['directory']
4729
def run(self, location=None, directory=u'.'):
4730
b, relpath = Branch.open_containing(directory)
4698
def run(self, location=None):
4699
b, relpath = Branch.open_containing(u'.')
4731
4700
if location is None:
4733
4702
location = b.get_old_bound_location()
4761
4730
_see_also = ['checkouts', 'bind']
4762
4731
takes_args = []
4763
takes_options = ['directory']
4765
def run(self, directory=u'.'):
4766
b, relpath = Branch.open_containing(directory)
4735
b, relpath = Branch.open_containing(u'.')
4767
4736
if not b.unbind():
4768
4737
raise errors.BzrCommandError('Local branch is not bound')
4815
4784
b = control.open_branch()
4817
4786
if tree is not None:
4818
self.add_cleanup(tree.lock_write().unlock)
4788
self.add_cleanup(tree.unlock)
4820
self.add_cleanup(b.lock_write().unlock)
4791
self.add_cleanup(b.unlock)
4821
4792
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4823
4794
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4862
4833
self.outf.write('The above revision(s) will be removed.\n')
4865
if not ui.ui_factory.confirm_action(
4866
'Uncommit these revisions',
4867
'bzrlib.builtins.uncommit',
4869
self.outf.write('Canceled\n')
4836
if not ui.ui_factory.get_boolean('Are you sure'):
4837
self.outf.write('Canceled')
4872
4840
mutter('Uncommitting from {%s} to {%s}',
4880
4848
class cmd_break_lock(Command):
4881
__doc__ = """Break a dead lock.
4883
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.
4886
4851
CAUTION: Locks should only be broken when you are sure that the process
4887
4852
holding the lock has been stopped.
4894
4859
bzr break-lock bzr+ssh://example.com/bzr/foo
4895
bzr break-lock --conf ~/.bazaar
4898
4861
takes_args = ['location?']
4901
help='LOCATION is the directory where the config lock is.'),
4903
help='Do not ask for confirmation before breaking the lock.'),
4906
def run(self, location=None, config=False, force=False):
4863
def run(self, location=None, show=False):
4907
4864
if location is None:
4908
4865
location = u'.'
4910
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
4912
{'bzrlib.lockdir.break': True})
4914
conf = _mod_config.LockableConfig(file_name=location)
4917
control, relpath = bzrdir.BzrDir.open_containing(location)
4919
control.break_lock()
4920
except NotImplementedError:
4866
control, relpath = bzrdir.BzrDir.open_containing(location)
4868
control.break_lock()
4869
except NotImplementedError:
4924
4873
class cmd_wait_until_signalled(Command):
4953
4902
'result in a dynamically allocated port. The default port '
4954
4903
'depends on the protocol.',
4956
custom_help('directory',
4957
help='Serve contents of this directory.'),
4906
help='Serve contents of this directory.',
4958
4908
Option('allow-writes',
4959
4909
help='By default the server is a readonly server. Supplying '
4960
4910
'--allow-writes enables write access to the contents of '
4988
4938
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4989
4939
protocol=None):
4990
from bzrlib import transport
4940
from bzrlib.transport import get_transport, transport_server_registry
4991
4941
if directory is None:
4992
4942
directory = os.getcwd()
4993
4943
if protocol is None:
4994
protocol = transport.transport_server_registry.get()
4944
protocol = transport_server_registry.get()
4995
4945
host, port = self.get_host_and_port(port)
4996
4946
url = urlutils.local_path_to_url(directory)
4997
4947
if not allow_writes:
4998
4948
url = 'readonly+' + url
4999
t = transport.get_transport(url)
5000
protocol(t, host, port, inet)
4949
transport = get_transport(url)
4950
protocol(transport, host, port, inet)
5003
4953
class cmd_join(Command):
5009
4959
not part of it. (Such trees can be produced by "bzr split", but also by
5010
4960
running "bzr branch" with the target inside a tree.)
5012
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
5013
4963
part. This is marked as a merge of the subtree into the containing tree,
5014
4964
and all history is preserved.
5115
5064
encoding_type = 'exact'
5117
5066
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5118
sign=False, revision=None, mail_to=None, message=None,
5067
sign=False, revision=None, mail_to=None, message=None):
5120
5068
from bzrlib.revision import ensure_null, NULL_REVISION
5121
5069
include_patch, include_bundle = {
5122
5070
'plain': (False, False),
5123
5071
'diff': (True, False),
5124
5072
'bundle': (True, True),
5126
branch = Branch.open(directory)
5074
branch = Branch.open('.')
5127
5075
stored_submit_branch = branch.get_submit_branch()
5128
5076
if submit_branch is None:
5129
5077
submit_branch = stored_submit_branch
5214
5162
given, in which case it is sent to a file.
5216
5164
Mail is sent using your preferred mail program. This should be transparent
5217
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.
5218
5166
If the preferred client can't be found (or used), your editor will be used.
5220
5168
To use a specific mail program, set the mail_client configuration option.
5391
5339
Option('delete',
5392
5340
help='Delete this tag rather than placing it.',
5394
custom_help('directory',
5395
help='Branch in which to place the tag.'),
5343
help='Branch in which to place the tag.',
5396
5347
Option('force',
5397
5348
help='Replace existing tags.',
5408
5359
branch, relpath = Branch.open_containing(directory)
5409
self.add_cleanup(branch.lock_write().unlock)
5361
self.add_cleanup(branch.unlock)
5411
5363
if tag_name is None:
5412
5364
raise errors.BzrCommandError("No tag specified to delete.")
5413
5365
branch.tags.delete_tag(tag_name)
5414
note('Deleted tag %s.' % tag_name)
5366
self.outf.write('Deleted tag %s.\n' % tag_name)
5417
5369
if len(revision) != 1:
5429
5381
if (not force) and branch.tags.has_tag(tag_name):
5430
5382
raise errors.TagAlreadyExists(tag_name)
5431
5383
branch.tags.set_tag(tag_name, revision_id)
5432
note('Created tag %s.' % tag_name)
5384
self.outf.write('Created tag %s.\n' % tag_name)
5435
5387
class cmd_tags(Command):
5441
5393
_see_also = ['tag']
5442
5394
takes_options = [
5443
custom_help('directory',
5444
help='Branch whose tags should be displayed.'),
5396
help='Branch whose tags should be displayed.',
5445
5400
RegistryOption.from_kwargs('sort',
5446
5401
'Sort tags by different criteria.', title='Sorting',
5447
natural='Sort numeric substrings as numbers:'
5448
' suitable for version numbers. (default)',
5449
alpha='Sort tags lexicographically.',
5402
alpha='Sort tags lexicographically (default).',
5450
5403
time='Sort tags chronologically.',
5469
self.add_cleanup(branch.lock_read().unlock)
5423
self.add_cleanup(branch.unlock)
5471
5425
graph = branch.repository.get_graph()
5472
5426
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5474
5428
# only show revisions between revid1 and revid2 (inclusive)
5475
5429
tags = [(tag, revid) for tag, revid in tags if
5476
5430
graph.is_between(revid, revid1, revid2)]
5477
if sort == 'natural':
5478
def natural_sort_key(tag):
5479
return [f(s) for f,s in
5480
zip(itertools.cycle((unicode.lower,int)),
5481
re.split('([0-9]+)', tag[0]))]
5482
tags.sort(key=natural_sort_key)
5483
elif sort == 'alpha':
5485
5433
elif sort == 'time':
5486
5434
timestamps = {}
5627
5575
takes_args = ['to_location?']
5628
takes_options = ['directory',
5576
takes_options = [Option('force',
5630
5577
help='Switch even if local commits will be lost.'),
5632
5579
Option('create-branch', short_name='b',
5637
5584
def run(self, to_location=None, force=False, create_branch=False,
5638
revision=None, directory=u'.'):
5639
5586
from bzrlib import switch
5640
tree_location = directory
5641
5588
revision = _get_one_revision('switch', revision)
5642
5589
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5643
5590
if to_location is None:
5644
5591
if revision is None:
5645
5592
raise errors.BzrCommandError('You must supply either a'
5646
5593
' revision or a location')
5647
to_location = tree_location
5649
5596
branch = control_dir.open_branch()
5650
5597
had_explicit_nick = branch.get_config().has_explicit_nickname()
5788
tree, file_list = WorkingTree.open_containing_paths(file_list,
5735
tree, file_list = tree_files(file_list, apply_view=False)
5790
5736
current_view, view_dict = tree.views.get_view_info()
5791
5737
if name is None:
5792
5738
name = current_view
5922
5868
You can put multiple items on the shelf, and by default, 'unshelve' will
5923
5869
restore the most recently shelved changes.
5925
For complicated changes, it is possible to edit the changes in a separate
5926
editor program to decide what the file remaining in the working copy
5927
should look like. To do this, add the configuration option
5929
change_editor = PROGRAM @new_path @old_path
5931
where @new_path is replaced with the path of the new version of the
5932
file and @old_path is replaced with the path of the old version of
5933
the file. The PROGRAM should save the new file with the desired
5934
contents of the file in the working tree.
5938
5872
takes_args = ['file*']
5940
5874
takes_options = [
5943
5876
Option('all', help='Shelve all changes.'),
5950
5883
Option('destroy',
5951
5884
help='Destroy removed changes instead of shelving them.'),
5953
_see_also = ['unshelve', 'configuration']
5886
_see_also = ['unshelve']
5955
5888
def run(self, revision=None, all=False, file_list=None, message=None,
5956
writer=None, list=False, destroy=False, directory=None):
5889
writer=None, list=False, destroy=False):
5958
return self.run_for_list(directory=directory)
5891
return self.run_for_list()
5959
5892
from bzrlib.shelf_ui import Shelver
5960
5893
if writer is None:
5961
5894
writer = bzrlib.option.diff_writer_registry.get()
5963
5896
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5964
file_list, message, destroy=destroy, directory=directory)
5897
file_list, message, destroy=destroy)
5969
5902
except errors.UserAbort:
5972
def run_for_list(self, directory=None):
5973
if directory is None:
5975
tree = WorkingTree.open_containing(directory)[0]
5976
self.add_cleanup(tree.lock_read().unlock)
5905
def run_for_list(self):
5906
tree = WorkingTree.open_containing('.')[0]
5908
self.add_cleanup(tree.unlock)
5977
5909
manager = tree.get_shelf_manager()
5978
5910
shelves = manager.active_shelves()
5979
5911
if len(shelves) == 0:
5998
5930
takes_args = ['shelf_id?']
5999
5931
takes_options = [
6001
5932
RegistryOption.from_kwargs(
6002
5933
'action', help="The action to perform.",
6003
5934
enum_switch=False, value_switches=True,
6012
5943
_see_also = ['shelve']
6014
def run(self, shelf_id=None, action='apply', directory=u'.'):
5945
def run(self, shelf_id=None, action='apply'):
6015
5946
from bzrlib.shelf_ui import Unshelver
6016
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5947
unshelver = Unshelver.from_args(shelf_id, action)
6018
5949
unshelver.run()
6036
5967
To check what clean-tree will do, use --dry-run.
6038
takes_options = ['directory',
6039
Option('ignored', help='Delete all ignored files.'),
5969
takes_options = [Option('ignored', help='Delete all ignored files.'),
6040
5970
Option('detritus', help='Delete conflict files, merge'
6041
5971
' backups, and failed selftest dirs.'),
6042
5972
Option('unknown',
6045
5975
' deleting them.'),
6046
5976
Option('force', help='Do not prompt before deleting.')]
6047
5977
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6048
force=False, directory=u'.'):
6049
5979
from bzrlib.clean_tree import clean_tree
6050
5980
if not (unknown or ignored or detritus):
6054
clean_tree(directory, unknown=unknown, ignored=ignored,
6055
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)
6058
5988
class cmd_reference(Command):
6107
6037
# be only called once.
6108
6038
for (name, aliases, module_name) in [
6109
6039
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6110
('cmd_config', [], 'bzrlib.config'),
6111
6040
('cmd_dpush', [], 'bzrlib.foreign'),
6112
6041
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6113
6042
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6114
6043
('cmd_conflicts', [], 'bzrlib.conflicts'),
6115
6044
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6116
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6118
6046
builtin_command_registry.register_lazy(name, aliases, module_name)