71
76
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
79
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
74
80
def tree_files(file_list, default_branch=u'.', canonicalize=True,
77
return internal_tree_files(file_list, default_branch, canonicalize,
79
except errors.FileInWrongBranch, e:
80
raise errors.BzrCommandError("%s is not in the same branch as %s" %
81
(e.path, file_list[0]))
82
return internal_tree_files(file_list, default_branch, canonicalize,
84
86
def tree_files_for_add(file_list):
149
151
# XXX: Bad function name; should possibly also be a class method of
150
152
# WorkingTree rather than a function.
153
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
151
154
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
152
155
apply_view=True):
153
156
"""Convert command-line paths to a WorkingTree and relative paths.
158
Deprecated: use WorkingTree.open_containing_paths instead.
155
160
This is typically used for command-line processors that take one or
156
161
more filenames, and infer the workingtree that contains them.
168
173
:return: workingtree, [relative_paths]
170
if file_list is None or len(file_list) == 0:
171
tree = WorkingTree.open_containing(default_branch)[0]
172
if tree.supports_views() and apply_view:
173
view_files = tree.views.lookup_view()
175
file_list = view_files
176
view_str = views.view_display_str(view_files)
177
note("Ignoring files outside view. View is %s" % view_str)
178
return tree, file_list
179
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
180
return tree, safe_relpath_files(tree, file_list, canonicalize,
181
apply_view=apply_view)
184
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
185
"""Convert file_list into a list of relpaths in tree.
187
:param tree: A tree to operate on.
188
:param file_list: A list of user provided paths or None.
189
:param apply_view: if True and a view is set, apply it or check that
190
specified files are within it
191
:return: A list of relative paths.
192
:raises errors.PathNotChild: When a provided path is in a different tree
195
if file_list is None:
197
if tree.supports_views() and apply_view:
198
view_files = tree.views.lookup_view()
202
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
203
# doesn't - fix that up here before we enter the loop.
205
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
208
for filename in file_list:
210
relpath = fixer(osutils.dereference_path(filename))
211
if view_files and not osutils.is_inside_any(view_files, relpath):
212
raise errors.FileOutsideView(filename, view_files)
213
new_list.append(relpath)
214
except errors.PathNotChild:
215
raise errors.FileInWrongBranch(tree.branch, filename)
175
return WorkingTree.open_containing_paths(
176
file_list, default_directory='.',
219
181
def _get_view_info_for_change_reporter(tree):
193
def _open_directory_or_containing_tree_or_branch(filename, directory):
194
"""Open the tree or branch containing the specified file, unless
195
the --directory option is used to specify a different branch."""
196
if directory is not None:
197
return (None, Branch.open(directory), filename)
198
return bzrdir.BzrDir.open_containing_tree_or_branch(filename)
231
201
# TODO: Make sure no commands unconditionally use the working directory as a
232
202
# branch. If a filename argument is used, the first of them should be used to
233
203
# specify the branch. (Perhaps this can be factored out into some kind of
282
252
To skip the display of pending merge information altogether, use
283
253
the no-pending option or specify a file/directory.
285
If a revision argument is given, the status is calculated against
286
that revision, or between two revisions if two are provided.
255
To compare the working directory to a specific revision, pass a
256
single revision to the revision argument.
258
To see which files have changed in a specific revision, or between
259
two revisions, pass a revision range to the revision argument.
260
This will produce the same results as calling 'bzr diff --summarize'.
289
263
# TODO: --no-recurse, --recurse options
311
285
raise errors.BzrCommandError('bzr status --revision takes exactly'
312
286
' one or two revision specifiers')
314
tree, relfile_list = tree_files(file_list)
288
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
315
289
# Avoid asking for specific files when that is not needed.
316
290
if relfile_list == ['']:
317
291
relfile_list = None
349
323
self.outf.write(revtext.decode('utf-8'))
352
def run(self, revision_id=None, revision=None):
326
def run(self, revision_id=None, revision=None, directory=u'.'):
353
327
if revision_id is not None and revision is not None:
354
328
raise errors.BzrCommandError('You can only supply one of'
355
329
' revision_id or --revision')
356
330
if revision_id is None and revision is None:
357
331
raise errors.BzrCommandError('You must supply either'
358
332
' --revision or a revision_id')
359
b = WorkingTree.open_containing(u'.')[0].branch
333
b = WorkingTree.open_containing(directory)[0].branch
361
335
revisions = b.repository.revisions
362
336
if revisions is None:
388
362
class cmd_dump_btree(Command):
389
"""Dump the contents of a btree index file to stdout.
363
__doc__ = """Dump the contents of a btree index file to stdout.
391
365
PATH is a btree index file, it can be any URL. This includes things like
392
366
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
500
474
if (working.has_changes()):
501
475
raise errors.UncommittedChanges(working)
476
if working.get_shelf_manager().last_shelf() is not None:
477
raise errors.ShelvedChanges(working)
503
working_path = working.bzrdir.root_transport.base
504
branch_path = working.branch.bzrdir.root_transport.base
505
if working_path != branch_path:
479
if working.user_url != working.branch.user_url:
506
480
raise errors.BzrCommandError("You cannot remove the working tree"
507
481
" from a lightweight checkout")
528
502
wt = WorkingTree.open_containing(location)[0]
503
self.add_cleanup(wt.lock_read().unlock)
530
504
except (errors.NoWorkingTree, errors.NotLocalUrl):
531
505
raise errors.NoWorkingTree(location)
532
self.add_cleanup(wt.unlock)
533
506
revid = wt.last_revision()
535
508
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
538
511
revno = ".".join(str(n) for n in revno_t)
540
513
b = Branch.open_containing(location)[0]
542
self.add_cleanup(b.unlock)
514
self.add_cleanup(b.lock_read().unlock)
543
515
revno = b.revno()
544
516
self.cleanup_now()
545
517
self.outf.write(str(revno) + '\n')
548
520
class cmd_revision_info(Command):
549
"""Show revision number and revision id for a given revision identifier.
521
__doc__ = """Show revision number and revision id for a given revision identifier.
552
524
takes_args = ['revision_info*']
553
525
takes_options = [
527
custom_help('directory',
556
528
help='Branch to examine, '
557
'rather than the one containing the working directory.',
529
'rather than the one containing the working directory.'),
561
530
Option('tree', help='Show revno of working tree'),
569
538
wt = WorkingTree.open_containing(directory)[0]
572
self.add_cleanup(wt.unlock)
540
self.add_cleanup(wt.lock_read().unlock)
573
541
except (errors.NoWorkingTree, errors.NotLocalUrl):
575
543
b = Branch.open_containing(directory)[0]
577
self.add_cleanup(b.unlock)
544
self.add_cleanup(b.lock_read().unlock)
578
545
revision_ids = []
579
546
if revision is not None:
580
547
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
679
646
should_print=(not is_quiet()))
682
base_tree.lock_read()
683
self.add_cleanup(base_tree.unlock)
649
self.add_cleanup(base_tree.lock_read().unlock)
684
650
tree, file_list = tree_files_for_add(file_list)
685
651
added, ignored = tree.smart_add(file_list, not
686
652
no_recurse, action=action, save=not dry_run)
757
723
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
759
725
revision = _get_one_revision('inventory', revision)
760
work_tree, file_list = tree_files(file_list)
761
work_tree.lock_read()
762
self.add_cleanup(work_tree.unlock)
726
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
727
self.add_cleanup(work_tree.lock_read().unlock)
763
728
if revision is not None:
764
729
tree = revision.as_tree(work_tree.branch)
766
731
extra_trees = [work_tree]
768
self.add_cleanup(tree.unlock)
732
self.add_cleanup(tree.lock_read().unlock)
831
795
if len(names_list) < 2:
832
796
raise errors.BzrCommandError("missing file argument")
833
tree, rel_names = tree_files(names_list, canonicalize=False)
834
tree.lock_tree_write()
835
self.add_cleanup(tree.unlock)
797
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
798
self.add_cleanup(tree.lock_tree_write().unlock)
836
799
self._run(tree, names_list, rel_names, after)
838
801
def run_auto(self, names_list, after, dry_run):
843
806
raise errors.BzrCommandError('--after cannot be specified with'
845
work_tree, file_list = tree_files(names_list, default_branch='.')
846
work_tree.lock_tree_write()
847
self.add_cleanup(work_tree.unlock)
808
work_tree, file_list = WorkingTree.open_containing_paths(
809
names_list, default_directory='.')
810
self.add_cleanup(work_tree.lock_tree_write().unlock)
848
811
rename_map.RenameMap.guess_renames(work_tree, dry_run)
850
813
def _run(self, tree, names_list, rel_names, after):
958
921
takes_options = ['remember', 'overwrite', 'revision',
959
922
custom_help('verbose',
960
923
help='Show logs of pulled revisions.'),
924
custom_help('directory',
962
925
help='Branch to pull into, '
963
'rather than the one containing the working directory.',
926
'rather than the one containing the working directory.'),
968
928
help="Perform a local pull in a bound "
969
929
"branch. Local pulls are not applied to "
970
930
"the master branch."
933
help="Show base revision text in conflicts.")
973
935
takes_args = ['location?']
974
936
encoding_type = 'replace'
976
938
def run(self, location=None, remember=False, overwrite=False,
977
939
revision=None, verbose=False,
978
directory=None, local=False):
940
directory=None, local=False,
979
942
# FIXME: too much stuff is in the command class
980
943
revision_id = None
985
948
tree_to = WorkingTree.open_containing(directory)[0]
986
949
branch_to = tree_to.branch
950
self.add_cleanup(tree_to.lock_write().unlock)
987
951
except errors.NoWorkingTree:
989
953
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.")
991
959
if local and not branch_to.get_bound_location():
992
960
raise errors.LocalRequiresBoundBranch()
1024
992
branch_from = Branch.open(location,
1025
993
possible_transports=possible_transports)
994
self.add_cleanup(branch_from.lock_read().unlock)
1027
996
if branch_to.get_parent() is None or remember:
1028
997
branch_to.set_parent(branch_from.base)
1030
if branch_from is not branch_to:
1031
branch_from.lock_read()
1032
self.add_cleanup(branch_from.unlock)
1033
999
if revision is not None:
1034
1000
revision_id = revision.as_revision_id(branch_from)
1036
branch_to.lock_write()
1037
self.add_cleanup(branch_to.unlock)
1038
1002
if tree_to is not None:
1039
1003
view_info = _get_view_info_for_change_reporter(tree_to)
1040
1004
change_reporter = delta._ChangeReporter(
1042
1006
view_info=view_info)
1043
1007
result = tree_to.pull(
1044
1008
branch_from, overwrite, revision_id, change_reporter,
1045
possible_transports=possible_transports, local=local)
1009
possible_transports=possible_transports, local=local,
1010
show_base=show_base)
1047
1012
result = branch_to.pull(
1048
1013
branch_from, overwrite, revision_id, local=local)
1085
1050
Option('create-prefix',
1086
1051
help='Create the path leading up to the branch '
1087
1052
'if it does not already exist.'),
1053
custom_help('directory',
1089
1054
help='Branch to push from, '
1090
'rather than the one containing the working directory.',
1055
'rather than the one containing the working directory.'),
1094
1056
Option('use-existing-dir',
1095
1057
help='By default push will fail if the target'
1096
1058
' directory exists, but does not already'
1107
1069
Option('strict',
1108
1070
help='Refuse to push if there are uncommitted changes in'
1109
1071
' the working tree, --no-strict disables the check.'),
1073
help="Don't populate the working tree, even for protocols"
1074
" that support it."),
1111
1076
takes_args = ['location?']
1112
1077
encoding_type = 'replace'
1114
1079
def run(self, location=None, remember=False, overwrite=False,
1115
1080
create_prefix=False, verbose=False, revision=None,
1116
1081
use_existing_dir=False, directory=None, stacked_on=None,
1117
stacked=False, strict=None):
1082
stacked=False, strict=None, no_tree=False):
1118
1083
from bzrlib.push import _show_push_branch
1120
1085
if directory is None:
1122
1087
# Get the source branch
1123
1088
(tree, br_from,
1124
1089
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1126
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1127
if strict is None: strict = True # default value
1128
1090
# Get the tip's revision_id
1129
1091
revision = _get_one_revision('push', revision)
1130
1092
if revision is not None:
1131
1093
revision_id = revision.in_history(br_from).rev_id
1133
1095
revision_id = None
1134
if strict and tree is not None and revision_id is None:
1135
if (tree.has_changes()):
1136
raise errors.UncommittedChanges(
1137
tree, more='Use --no-strict to force the push.')
1138
if tree.last_revision() != tree.branch.last_revision():
1139
# The tree has lost sync with its branch, there is little
1140
# chance that the user is aware of it but he can still force
1141
# the push with --no-strict
1142
raise errors.OutOfDateTree(
1143
tree, more='Use --no-strict to force the push.')
1096
if tree is not None and revision_id is None:
1097
tree.check_changed_or_out_of_date(
1098
strict, 'push_strict',
1099
more_error='Use --no-strict to force the push.',
1100
more_warning='Uncommitted changes will not be pushed.')
1145
1101
# Get the stacked_on branch, if any
1146
1102
if stacked_on is not None:
1147
1103
stacked_on = urlutils.normalize_url(stacked_on)
1175
1131
_show_push_branch(br_from, revision_id, location, self.outf,
1176
1132
verbose=verbose, overwrite=overwrite, remember=remember,
1177
1133
stacked_on=stacked_on, create_prefix=create_prefix,
1178
use_existing_dir=use_existing_dir)
1134
use_existing_dir=use_existing_dir, no_tree=no_tree)
1181
1137
class cmd_branch(Command):
1182
"""Create a new branch that is a copy of an existing branch.
1138
__doc__ = """Create a new branch that is a copy of an existing branch.
1184
1140
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1185
1141
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1195
1151
_see_also = ['checkout']
1196
1152
takes_args = ['from_location', 'to_location?']
1197
takes_options = ['revision', Option('hardlink',
1198
help='Hard-link working tree files where possible.'),
1153
takes_options = ['revision',
1154
Option('hardlink', help='Hard-link working tree files where possible.'),
1155
Option('files-from', type=str,
1156
help="Get file contents from this tree."),
1199
1157
Option('no-tree',
1200
1158
help="Create a branch without a working-tree."),
1201
1159
Option('switch',
1220
1178
def run(self, from_location, to_location=None, revision=None,
1221
1179
hardlink=False, stacked=False, standalone=False, no_tree=False,
1222
use_existing_dir=False, switch=False, bind=False):
1180
use_existing_dir=False, switch=False, bind=False,
1223
1182
from bzrlib import switch as _mod_switch
1224
1183
from bzrlib.tag import _merge_tags_if_possible
1225
1184
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1186
if not (hardlink or files_from):
1187
# accelerator_tree is usually slower because you have to read N
1188
# files (no readahead, lots of seeks, etc), but allow the user to
1189
# explicitly request it
1190
accelerator_tree = None
1191
if files_from is not None and files_from != from_location:
1192
accelerator_tree = WorkingTree.open(files_from)
1227
1193
revision = _get_one_revision('branch', revision)
1229
self.add_cleanup(br_from.unlock)
1194
self.add_cleanup(br_from.lock_read().unlock)
1230
1195
if revision is not None:
1231
1196
revision_id = revision.as_revision_id(br_from)
1337
1302
to_location = branch_location
1338
1303
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1339
1304
branch_location)
1305
if not (hardlink or files_from):
1306
# accelerator_tree is usually slower because you have to read N
1307
# files (no readahead, lots of seeks, etc), but allow the user to
1308
# explicitly request it
1309
accelerator_tree = None
1340
1310
revision = _get_one_revision('checkout', revision)
1341
if files_from is not None:
1311
if files_from is not None and files_from != branch_location:
1342
1312
accelerator_tree = WorkingTree.open(files_from)
1343
1313
if revision is not None:
1344
1314
revision_id = revision.as_revision_id(source)
1372
1342
@display_command
1373
1343
def run(self, dir=u'.'):
1374
1344
tree = WorkingTree.open_containing(dir)[0]
1376
self.add_cleanup(tree.unlock)
1345
self.add_cleanup(tree.lock_read().unlock)
1377
1346
new_inv = tree.inventory
1378
1347
old_tree = tree.basis_tree()
1379
old_tree.lock_read()
1380
self.add_cleanup(old_tree.unlock)
1348
self.add_cleanup(old_tree.lock_read().unlock)
1381
1349
old_inv = old_tree.inventory
1383
1351
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1395
1363
class cmd_update(Command):
1396
"""Update a tree to have the latest code committed to its branch.
1364
__doc__ = """Update a tree to have the latest code committed to its branch.
1398
1366
This will perform a merge into the working tree, and may generate
1399
1367
conflicts. If you have any local changes, you will still
1402
1370
If you want to discard your local changes, you can just do a
1403
1371
'bzr revert' instead of 'bzr commit' after the update.
1373
If you want to restore a file that has been removed locally, use
1374
'bzr revert' instead of 'bzr update'.
1405
1376
If the tree's branch is bound to a master branch, it will also update
1406
1377
the branch from the master.
1409
1380
_see_also = ['pull', 'working-trees', 'status-flags']
1410
1381
takes_args = ['dir?']
1411
takes_options = ['revision']
1382
takes_options = ['revision',
1384
help="Show base revision text in conflicts."),
1412
1386
aliases = ['up']
1414
def run(self, dir='.', revision=None):
1388
def run(self, dir='.', revision=None, show_base=None):
1415
1389
if revision is not None and len(revision) != 1:
1416
1390
raise errors.BzrCommandError(
1417
1391
"bzr update --revision takes exactly one revision")
1421
1395
master = branch.get_master_branch(
1422
1396
possible_transports=possible_transports)
1423
1397
if master is not None:
1425
1398
branch_location = master.base
1401
branch_location = tree.branch.base
1427
1402
tree.lock_tree_write()
1428
branch_location = tree.branch.base
1429
1403
self.add_cleanup(tree.unlock)
1430
1404
# get rid of the final '/' and be ready for display
1431
1405
branch_location = urlutils.unescape_for_display(
1445
1419
revision_id = branch.last_revision()
1446
1420
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1447
revno = branch.revision_id_to_revno(revision_id)
1448
note("Tree is up to date at revision %d of branch %s" %
1449
(revno, branch_location))
1421
revno = branch.revision_id_to_dotted_revno(revision_id)
1422
note("Tree is up to date at revision %s of branch %s" %
1423
('.'.join(map(str, revno)), branch_location))
1451
1425
view_info = _get_view_info_for_change_reporter(tree)
1452
1426
change_reporter = delta._ChangeReporter(
1457
1431
change_reporter,
1458
1432
possible_transports=possible_transports,
1459
1433
revision=revision_id,
1435
show_base=show_base)
1461
1436
except errors.NoSuchRevision, e:
1462
1437
raise errors.BzrCommandError(
1463
1438
"branch has no revision %s\n"
1464
1439
"bzr update --revision only works"
1465
1440
" for a revision in the branch history"
1466
1441
% (e.revision))
1467
revno = tree.branch.revision_id_to_revno(
1442
revno = tree.branch.revision_id_to_dotted_revno(
1468
1443
_mod_revision.ensure_null(tree.last_revision()))
1469
note('Updated to revision %d of branch %s' %
1470
(revno, branch_location))
1471
if tree.get_parent_ids()[1:] != existing_pending_merges:
1444
note('Updated to revision %s of branch %s' %
1445
('.'.join(map(str, revno)), branch_location))
1446
parent_ids = tree.get_parent_ids()
1447
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1472
1448
note('Your local commits will now show as pending merges with '
1473
1449
"'bzr status', and can be committed with 'bzr commit'.")
1474
1450
if conflicts != 0:
1524
1500
class cmd_remove(Command):
1525
"""Remove files or directories.
1501
__doc__ = """Remove files or directories.
1527
This makes bzr stop tracking changes to the specified files. bzr will delete
1528
them if they can easily be recovered using revert. If no options or
1529
parameters are given bzr will scan for files that are being tracked by bzr
1530
but missing in your tree and stop tracking them for you.
1503
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1504
delete them if they can easily be recovered using revert otherwise they
1505
will be backed up (adding an extention of the form .~#~). If no options or
1506
parameters are given Bazaar will scan for files that are being tracked by
1507
Bazaar but missing in your tree and stop tracking them for you.
1532
1509
takes_args = ['file*']
1533
1510
takes_options = ['verbose',
1535
1512
RegistryOption.from_kwargs('file-deletion-strategy',
1536
1513
'The file deletion mode to be used.',
1537
1514
title='Deletion Strategy', value_switches=True, enum_switch=False,
1538
safe='Only delete files if they can be'
1539
' safely recovered (default).',
1515
safe='Backup changed files (default).',
1540
1516
keep='Delete from bzr but leave the working copy.',
1517
no_backup='Don\'t backup changed files.',
1541
1518
force='Delete all the specified files, even if they can not be '
1542
'recovered and even if they are non-empty directories.')]
1519
'recovered and even if they are non-empty directories. '
1520
'(deprecated, use no-backup)')]
1543
1521
aliases = ['rm', 'del']
1544
1522
encoding_type = 'replace'
1546
1524
def run(self, file_list, verbose=False, new=False,
1547
1525
file_deletion_strategy='safe'):
1548
tree, file_list = tree_files(file_list)
1526
if file_deletion_strategy == 'force':
1527
note("(The --force option is deprecated, rather use --no-backup "
1529
file_deletion_strategy = 'no-backup'
1531
tree, file_list = WorkingTree.open_containing_paths(file_list)
1550
1533
if file_list is not None:
1551
1534
file_list = [f for f in file_list]
1554
self.add_cleanup(tree.unlock)
1536
self.add_cleanup(tree.lock_write().unlock)
1555
1537
# Heuristics should probably all move into tree.remove_smart or
1572
1554
file_deletion_strategy = 'keep'
1573
1555
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1574
1556
keep_files=file_deletion_strategy=='keep',
1575
force=file_deletion_strategy=='force')
1557
force=(file_deletion_strategy=='no-backup'))
1578
1560
class cmd_file_id(Command):
1579
"""Print file_id of a particular file or directory.
1561
__doc__ = """Print file_id of a particular file or directory.
1581
1563
The file_id is assigned when the file is first added and remains the
1582
1564
same through all revisions where the file exists, even when it is
1641
1623
_see_also = ['check']
1642
1624
takes_args = ['branch?']
1626
Option('canonicalize-chks',
1627
help='Make sure CHKs are in canonical form (repairs '
1644
def run(self, branch="."):
1632
def run(self, branch=".", canonicalize_chks=False):
1645
1633
from bzrlib.reconcile import reconcile
1646
1634
dir = bzrdir.BzrDir.open(branch)
1635
reconcile(dir, canonicalize_chks=canonicalize_chks)
1650
1638
class cmd_revision_history(Command):
1651
"""Display the list of revision ids on a branch."""
1639
__doc__ = """Display the list of revision ids on a branch."""
1653
1641
_see_also = ['log']
1654
1642
takes_args = ['location?']
1728
1716
Option('append-revisions-only',
1729
1717
help='Never change revnos or the existing log.'
1730
' Append revisions to it only.')
1718
' Append revisions to it only.'),
1720
'Create a branch without a working tree.')
1732
1722
def run(self, location=None, format=None, append_revisions_only=False,
1733
create_prefix=False):
1723
create_prefix=False, no_tree=False):
1734
1724
if format is None:
1735
1725
format = bzrdir.format_registry.make_bzrdir('default')
1736
1726
if location is None:
1759
1749
except errors.NotBranchError:
1760
1750
# really a NotBzrDir error...
1761
1751
create_branch = bzrdir.BzrDir.create_branch_convenience
1753
force_new_tree = False
1755
force_new_tree = None
1762
1756
branch = create_branch(to_transport.base, format=format,
1763
possible_transports=[to_transport])
1757
possible_transports=[to_transport],
1758
force_new_tree=force_new_tree)
1764
1759
a_bzrdir = branch.bzrdir
1766
1761
from bzrlib.transport.local import LocalTransport
1770
1765
raise errors.BranchExistsWithoutWorkingTree(location)
1771
1766
raise errors.AlreadyBranchError(location)
1772
1767
branch = a_bzrdir.create_branch()
1773
a_bzrdir.create_workingtree()
1769
a_bzrdir.create_workingtree()
1774
1770
if append_revisions_only:
1776
1772
branch.set_append_revisions_only(True)
1860
1856
class cmd_diff(Command):
1861
"""Show differences in the working tree, between revisions or branches.
1857
__doc__ = """Show differences in the working tree, between revisions or branches.
1863
1859
If no arguments are given, all changes for the current tree are listed.
1864
1860
If files are given, only the changes in those files are listed.
1870
1866
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1871
1867
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
1875
1878
2 - unrepresentable changes
1950
1962
help='Use this command to compare files.',
1965
RegistryOption('format',
1966
help='Diff format to use.',
1967
lazy_registry=('bzrlib.diff', 'format_registry'),
1968
value_switches=False, title='Diff format'),
1954
1970
aliases = ['di', 'dif']
1955
1971
encoding_type = 'exact'
1957
1973
@display_command
1958
1974
def run(self, revision=None, file_list=None, diff_options=None,
1959
prefix=None, old=None, new=None, using=None):
1960
from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
1975
prefix=None, old=None, new=None, using=None, format=None):
1976
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
1962
1979
if (prefix is None) or (prefix == '0'):
1963
1980
# diff -p0 format
1977
1994
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1978
1995
' one or two revision specifiers')
1997
if using is not None and format is not None:
1998
raise errors.BzrCommandError('--using and --format are mutually '
1980
2001
(old_tree, new_tree,
1981
2002
old_branch, new_branch,
1982
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1983
file_list, revision, old, new, apply_view=True)
2003
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2004
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()
1984
2007
return show_diff_trees(old_tree, new_tree, sys.stdout,
1985
2008
specific_files=specific_files,
1986
2009
external_diff_options=diff_options,
1987
2010
old_label=old_label, new_label=new_label,
1988
extra_trees=extra_trees, using=using)
2011
extra_trees=extra_trees,
2012
path_encoding=path_encoding,
1991
2017
class cmd_deleted(Command):
1992
"""List files deleted in the working tree.
2018
__doc__ = """List files deleted in the working tree.
1994
2020
# TODO: Show files deleted since a previous revision, or
1995
2021
# between two revisions.
1998
2024
# level of effort but possibly much less IO. (Or possibly not,
1999
2025
# if the directories are very large...)
2000
2026
_see_also = ['status', 'ls']
2001
takes_options = ['show-ids']
2027
takes_options = ['directory', 'show-ids']
2003
2029
@display_command
2004
def run(self, show_ids=False):
2005
tree = WorkingTree.open_containing(u'.')[0]
2007
self.add_cleanup(tree.unlock)
2030
def run(self, show_ids=False, directory=u'.'):
2031
tree = WorkingTree.open_containing(directory)[0]
2032
self.add_cleanup(tree.lock_read().unlock)
2008
2033
old = tree.basis_tree()
2010
self.add_cleanup(old.unlock)
2034
self.add_cleanup(old.lock_read().unlock)
2011
2035
for path, ie in old.inventory.iter_entries():
2012
2036
if not tree.has_id(ie.file_id):
2013
2037
self.outf.write(path)
2020
2044
class cmd_modified(Command):
2021
"""List files modified in working tree.
2045
__doc__ = """List files modified in working tree.
2025
2049
_see_also = ['status', 'ls']
2028
help='Write an ascii NUL (\\0) separator '
2029
'between files rather than a newline.')
2050
takes_options = ['directory', 'null']
2032
2052
@display_command
2033
def run(self, null=False):
2034
tree = WorkingTree.open_containing(u'.')[0]
2053
def run(self, null=False, directory=u'.'):
2054
tree = WorkingTree.open_containing(directory)[0]
2035
2055
td = tree.changes_from(tree.basis_tree())
2036
2056
for path, id, kind, text_modified, meta_modified in td.modified:
2043
2063
class cmd_added(Command):
2044
"""List files added in working tree.
2064
__doc__ = """List files added in working tree.
2048
2068
_see_also = ['status', 'ls']
2051
help='Write an ascii NUL (\\0) separator '
2052
'between files rather than a newline.')
2069
takes_options = ['directory', 'null']
2055
2071
@display_command
2056
def run(self, null=False):
2057
wt = WorkingTree.open_containing(u'.')[0]
2059
self.add_cleanup(wt.unlock)
2072
def run(self, null=False, directory=u'.'):
2073
wt = WorkingTree.open_containing(directory)[0]
2074
self.add_cleanup(wt.lock_read().unlock)
2060
2075
basis = wt.basis_tree()
2062
self.add_cleanup(basis.unlock)
2076
self.add_cleanup(basis.lock_read().unlock)
2063
2077
basis_inv = basis.inventory
2064
2078
inv = wt.inventory
2065
2079
for file_id in inv:
2068
2082
if inv.is_root(file_id) and len(basis_inv) == 0:
2070
2084
path = inv.id2path(file_id)
2071
if not os.access(osutils.abspath(path), os.F_OK):
2085
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2074
2088
self.outf.write(path + '\0')
2274
2288
help='Show just the specified revision.'
2275
2289
' 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'),
2277
2296
Option('levels',
2278
2297
short_name='n',
2279
2298
help='Number of levels to display - 0 for all, 1 for flat.',
2294
2313
help='Show changes made in each revision as a patch.'),
2295
2314
Option('include-merges',
2296
2315
help='Show merged revisions like --levels 0 does.'),
2316
Option('exclude-common-ancestry',
2317
help='Display only the revisions that are not part'
2318
' of both ancestries (require -rX..Y)'
2298
2321
encoding_type = 'replace'
2311
2334
show_diff=False,
2312
include_merges=False):
2335
include_merges=False,
2337
exclude_common_ancestry=False,
2313
2339
from bzrlib.log import (
2315
2341
make_log_request_dict,
2316
2342
_get_info_for_log_files,
2318
2344
direction = (forward and 'forward') or 'reverse'
2345
if (exclude_common_ancestry
2346
and (revision is None or len(revision) != 2)):
2347
raise errors.BzrCommandError(
2348
'--exclude-common-ancestry requires -r with two revisions')
2319
2349
if include_merges:
2320
2350
if levels is None:
2338
2368
# find the file ids to log and check for directory filtering
2339
2369
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2340
revision, file_list)
2341
self.add_cleanup(b.unlock)
2370
revision, file_list, self.add_cleanup)
2342
2371
for relpath, file_id, kind in file_info_list:
2343
2372
if file_id is None:
2344
2373
raise errors.BzrCommandError(
2363
2392
dir, relpath = bzrdir.BzrDir.open_containing(location)
2364
2393
b = dir.open_branch()
2366
self.add_cleanup(b.unlock)
2394
self.add_cleanup(b.lock_read().unlock)
2367
2395
rev1, rev2 = _get_revision_range(revision, b, self.name())
2369
2397
# Decide on the type of delta & diff filtering to use
2389
2417
show_timezone=timezone,
2390
2418
delta_format=get_verbosity_level(),
2392
show_advice=levels is None)
2420
show_advice=levels is None,
2421
author_list_handler=authors)
2394
2423
# Choose the algorithm for doing the logging. It's annoying
2395
2424
# having multiple code paths like this but necessary until
2414
2443
direction=direction, specific_fileids=file_ids,
2415
2444
start_revision=rev1, end_revision=rev2, limit=limit,
2416
2445
message_search=message, delta_type=delta_type,
2417
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2446
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2447
exclude_common_ancestry=exclude_common_ancestry,
2418
2449
Logger(b, rqst).show(lf)
2491
2522
tree, relpath = WorkingTree.open_containing(filename)
2492
2523
file_id = tree.path2id(relpath)
2493
2524
b = tree.branch
2495
self.add_cleanup(b.unlock)
2525
self.add_cleanup(b.lock_read().unlock)
2496
2526
touching_revs = log.find_touching_revisions(b, file_id)
2497
2527
for revno, revision_id, what in touching_revs:
2498
2528
self.outf.write("%6d %s\n" % (revno, what))
2501
2531
class cmd_ls(Command):
2502
"""List files in a tree.
2532
__doc__ = """List files in a tree.
2505
2535
_see_also = ['status', 'cat']
2511
2541
help='Recurse into subdirectories.'),
2512
2542
Option('from-root',
2513
2543
help='Print paths relative to the root of the branch.'),
2514
Option('unknown', help='Print unknown files.'),
2544
Option('unknown', short_name='u',
2545
help='Print unknown files.'),
2515
2546
Option('versioned', help='Print versioned files.',
2516
2547
short_name='V'),
2517
Option('ignored', help='Print ignored files.'),
2519
help='Write an ascii NUL (\\0) separator '
2520
'between files rather than a newline.'),
2548
Option('ignored', short_name='i',
2549
help='Print ignored files.'),
2550
Option('kind', short_name='k',
2522
2551
help='List entries of a particular kind: file, directory, symlink.',
2526
2557
@display_command
2527
2558
def run(self, revision=None, verbose=False,
2528
2559
recursive=False, from_root=False,
2529
2560
unknown=False, versioned=False, ignored=False,
2530
null=False, kind=None, show_ids=False, path=None):
2561
null=False, kind=None, show_ids=False, path=None, directory=None):
2532
2563
if kind and kind not in ('file', 'directory', 'symlink'):
2533
2564
raise errors.BzrCommandError('invalid kind specified')
2545
2576
raise errors.BzrCommandError('cannot specify both --from-root'
2548
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2579
tree, branch, relpath = \
2580
_open_directory_or_containing_tree_or_branch(fs_path, directory)
2551
2582
# Calculate the prefix to use
2567
2598
view_str = views.view_display_str(view_files)
2568
2599
note("Ignoring files outside view. View is %s" % view_str)
2571
self.add_cleanup(tree.unlock)
2601
self.add_cleanup(tree.lock_read().unlock)
2572
2602
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2573
2603
from_dir=relpath, recursive=recursive):
2574
2604
# Apply additional masking
2618
2648
class cmd_unknowns(Command):
2619
"""List unknown files.
2649
__doc__ = """List unknown files.
2623
2653
_see_also = ['ls']
2654
takes_options = ['directory']
2625
2656
@display_command
2627
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2657
def run(self, directory=u'.'):
2658
for f in WorkingTree.open_containing(directory)[0].unknowns():
2628
2659
self.outf.write(osutils.quotefn(f) + '\n')
2631
2662
class cmd_ignore(Command):
2632
"""Ignore specified files or patterns.
2663
__doc__ = """Ignore specified files or patterns.
2634
2665
See ``bzr help patterns`` for details on the syntax of patterns.
2644
2675
using this command or directly by using an editor, be sure to commit
2678
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2679
the global ignore file can be found in the application data directory as
2680
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2681
Global ignores are not touched by this command. The global ignore file
2682
can be edited directly using an editor.
2647
2684
Patterns prefixed with '!' are exceptions to ignore patterns and take
2648
2685
precedence over regular ignores. Such exceptions are used to specify
2649
2686
files that should be versioned which would otherwise be ignored.
2651
2688
Patterns prefixed with '!!' act as regular ignore patterns, but have
2652
2689
precedence over the '!' exception patterns.
2654
Note: ignore patterns containing shell wildcards must be quoted from
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.
2658
2700
Ignore the top level Makefile::
2690
2736
_see_also = ['status', 'ignored', 'patterns']
2691
2737
takes_args = ['name_pattern*']
2693
Option('old-default-rules',
2694
help='Write out the ignore rules bzr < 0.9 always used.')
2738
takes_options = ['directory',
2739
Option('default-rules',
2740
help='Display the default ignore rules that bzr uses.')
2697
def run(self, name_pattern_list=None, old_default_rules=None):
2743
def run(self, name_pattern_list=None, default_rules=None,
2698
2745
from bzrlib import ignores
2699
if old_default_rules is not None:
2700
# dump the rules and exit
2701
for pattern in ignores.OLD_DEFAULTS:
2746
if default_rules is not None:
2747
# dump the default rules and exit
2748
for pattern in ignores.USER_DEFAULTS:
2702
2749
self.outf.write("%s\n" % pattern)
2704
2751
if not name_pattern_list:
2705
2752
raise errors.BzrCommandError("ignore requires at least one "
2706
"NAME_PATTERN or --old-default-rules")
2753
"NAME_PATTERN or --default-rules.")
2707
2754
name_pattern_list = [globbing.normalize_pattern(p)
2708
2755
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('')
2709
2764
for name_pattern in name_pattern_list:
2710
2765
if (name_pattern[0] == '/' or
2711
2766
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2712
2767
raise errors.BzrCommandError(
2713
2768
"NAME_PATTERN should not be an absolute path")
2714
tree, relpath = WorkingTree.open_containing(u'.')
2769
tree, relpath = WorkingTree.open_containing(directory)
2715
2770
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2716
2771
ignored = globbing.Globster(name_pattern_list)
2773
self.add_cleanup(tree.lock_read().unlock)
2719
2774
for entry in tree.list_files():
2721
2776
if id is not None:
2722
2777
filename = entry[0]
2723
2778
if ignored.match(filename):
2724
2779
matches.append(filename)
2726
2780
if len(matches) > 0:
2727
2781
self.outf.write("Warning: the following files are version controlled and"
2728
2782
" match your ignore pattern:\n%s"
2744
2798
encoding_type = 'replace'
2745
2799
_see_also = ['ignore', 'ls']
2800
takes_options = ['directory']
2747
2802
@display_command
2749
tree = WorkingTree.open_containing(u'.')[0]
2751
self.add_cleanup(tree.unlock)
2803
def run(self, directory=u'.'):
2804
tree = WorkingTree.open_containing(directory)[0]
2805
self.add_cleanup(tree.lock_read().unlock)
2752
2806
for path, file_class, kind, file_id, entry in tree.list_files():
2753
2807
if file_class != 'I':
2760
2814
class cmd_lookup_revision(Command):
2761
"""Lookup the revision-id from a revision-number
2815
__doc__ = """Lookup the revision-id from a revision-number
2764
2818
bzr lookup-revision 33
2767
2821
takes_args = ['revno']
2822
takes_options = ['directory']
2769
2824
@display_command
2770
def run(self, revno):
2825
def run(self, revno, directory=u'.'):
2772
2827
revno = int(revno)
2773
2828
except ValueError:
2774
2829
raise errors.BzrCommandError("not a valid revision-number: %r"
2776
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2831
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2777
2832
self.outf.write("%s\n" % revid)
2780
2835
class cmd_export(Command):
2781
"""Export current or past revision to a destination directory or archive.
2836
__doc__ = """Export current or past revision to a destination directory or archive.
2783
2838
If no revision is specified this exports the last committed revision.
2821
2876
'revision in which it was changed.'),
2823
2878
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2824
root=None, filters=False, per_file_timestamps=False):
2879
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2825
2880
from bzrlib.export import export
2827
2882
if branch_or_subdir is None:
2828
tree = WorkingTree.open_containing(u'.')[0]
2883
tree = WorkingTree.open_containing(directory)[0]
2829
2884
b = tree.branch
2862
2917
@display_command
2863
2918
def run(self, filename, revision=None, name_from_revision=False,
2919
filters=False, directory=None):
2865
2920
if revision is not None and len(revision) != 1:
2866
2921
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2867
2922
" one revision specifier")
2868
2923
tree, branch, relpath = \
2869
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2871
self.add_cleanup(branch.unlock)
2924
_open_directory_or_containing_tree_or_branch(filename, directory)
2925
self.add_cleanup(branch.lock_read().unlock)
2872
2926
return self._run(tree, branch, relpath, filename, revision,
2873
2927
name_from_revision, filters)
3106
3159
properties = {}
3108
tree, selected_list = tree_files(selected_list)
3161
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3109
3162
if selected_list == ['']:
3110
3163
# workaround - commit of root of tree should be exactly the same
3111
3164
# as just default commit in that tree, and succeed even though
3136
3189
'(use --file "%(f)s" to take commit message from that file)'
3137
3190
% { 'f': message })
3138
3191
ui.ui_factory.show_warning(warning_msg)
3193
message = message.replace('\r\n', '\n')
3194
message = message.replace('\r', '\n')
3196
raise errors.BzrCommandError(
3197
"please specify either --message or --file")
3140
3199
def get_message(commit_obj):
3141
3200
"""Callback to get commit message"""
3142
my_message = message
3143
if my_message is not None and '\r' in my_message:
3144
my_message = my_message.replace('\r\n', '\n')
3145
my_message = my_message.replace('\r', '\n')
3146
if my_message is None and not file:
3147
t = make_commit_message_template_encoded(tree,
3204
my_message = f.read().decode(osutils.get_user_encoding())
3207
elif message is not None:
3208
my_message = message
3210
# No message supplied: make one up.
3211
# text is the status of the tree
3212
text = make_commit_message_template_encoded(tree,
3148
3213
selected_list, diff=show_diff,
3149
3214
output_encoding=osutils.get_user_encoding())
3215
# start_message is the template generated from hooks
3216
# XXX: Warning - looks like hooks return unicode,
3217
# make_commit_message_template_encoded returns user encoding.
3218
# We probably want to be using edit_commit_message instead to
3150
3220
start_message = generate_commit_message_template(commit_obj)
3151
my_message = edit_commit_message_encoded(t,
3221
my_message = edit_commit_message_encoded(text,
3152
3222
start_message=start_message)
3153
3223
if my_message is None:
3154
3224
raise errors.BzrCommandError("please specify a commit"
3155
3225
" message with either --message or --file")
3156
elif my_message and file:
3157
raise errors.BzrCommandError(
3158
"please specify either --message or --file")
3160
my_message = codecs.open(file, 'rt',
3161
osutils.get_user_encoding()).read()
3162
3226
if my_message == "":
3163
3227
raise errors.BzrCommandError("empty commit message specified")
3164
3228
return my_message
3174
3238
reporter=None, verbose=verbose, revprops=properties,
3175
3239
authors=author, timestamp=commit_stamp,
3176
3240
timezone=offset,
3177
exclude=safe_relpath_files(tree, exclude))
3241
exclude=tree.safe_relpath_files(exclude))
3178
3242
except PointlessCommit:
3179
# FIXME: This should really happen before the file is read in;
3180
# perhaps prepare the commit; get the message; then actually commit
3181
3243
raise errors.BzrCommandError("No changes to commit."
3182
3244
" Use --unchanged to commit anyhow.")
3183
3245
except ConflictsInTree:
3198
3260
class cmd_check(Command):
3199
"""Validate working tree structure, branch consistency and repository history.
3261
__doc__ = """Validate working tree structure, branch consistency and repository history.
3201
3263
This command checks various invariants about branch and repository storage
3202
3264
to detect data corruption or bzr bugs.
3302
3364
bzr whoami "Frank Chu <fchu@example.com>"
3304
takes_options = [ Option('email',
3366
takes_options = [ 'directory',
3305
3368
help='Display email address only.'),
3306
3369
Option('branch',
3307
3370
help='Set identity for the current branch instead of '
3311
3374
encoding_type = 'replace'
3313
3376
@display_command
3314
def run(self, email=False, branch=False, name=None):
3377
def run(self, email=False, branch=False, name=None, directory=None):
3315
3378
if name is None:
3316
# use branch if we're inside one; otherwise global config
3318
c = Branch.open_containing('.')[0].get_config()
3319
except errors.NotBranchError:
3320
c = config.GlobalConfig()
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()
3322
3388
self.outf.write(c.user_email() + '\n')
3327
3393
# display a warning if an email address isn't included in the given name.
3329
config.extract_email_address(name)
3395
_mod_config.extract_email_address(name)
3330
3396
except errors.NoEmailInUsername, e:
3331
3397
warning('"%s" does not seem to contain an email address. '
3332
3398
'This is allowed, but not recommended.', name)
3334
3400
# use global config unless --branch given
3336
c = Branch.open_containing('.')[0].get_config()
3402
if directory is None:
3403
c = Branch.open_containing(u'.')[0].get_config()
3405
c = Branch.open(directory).get_config()
3338
c = config.GlobalConfig()
3407
c = _mod_config.GlobalConfig()
3339
3408
c.set_user_option('email', name)
3342
3411
class cmd_nick(Command):
3343
"""Print or set the branch nickname.
3412
__doc__ = """Print or set the branch nickname.
3345
3414
If unset, the tree root directory name is used as the nickname.
3346
3415
To print the current nickname, execute with no argument.
3352
3421
_see_also = ['info']
3353
3422
takes_args = ['nickname?']
3354
def run(self, nickname=None):
3355
branch = Branch.open_containing(u'.')[0]
3423
takes_options = ['directory']
3424
def run(self, nickname=None, directory=u'.'):
3425
branch = Branch.open_containing(directory)[0]
3356
3426
if nickname is None:
3357
3427
self.printme(branch)
3407
3477
'bzr alias --remove expects an alias to remove.')
3408
3478
# If alias is not found, print something like:
3409
3479
# unalias: foo: not found
3410
c = config.GlobalConfig()
3480
c = _mod_config.GlobalConfig()
3411
3481
c.unset_alias(alias_name)
3413
3483
@display_command
3414
3484
def print_aliases(self):
3415
3485
"""Print out the defined aliases in a similar format to bash."""
3416
aliases = config.GlobalConfig().get_aliases()
3486
aliases = _mod_config.GlobalConfig().get_aliases()
3417
3487
for key, value in sorted(aliases.iteritems()):
3418
3488
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3430
3500
def set_alias(self, alias_name, alias_command):
3431
3501
"""Save the alias in the global config."""
3432
c = config.GlobalConfig()
3502
c = _mod_config.GlobalConfig()
3433
3503
c.set_alias(alias_name, alias_command)
3436
3506
class cmd_selftest(Command):
3437
"""Run internal test suite.
3507
__doc__ = """Run internal test suite.
3439
3509
If arguments are given, they are regular expressions that say which tests
3440
3510
should run. Tests matching any expression are run, and other tests are
3508
3581
'throughout the test suite.',
3509
3582
type=get_transport_type),
3510
3583
Option('benchmark',
3511
help='Run the benchmarks rather than selftests.'),
3584
help='Run the benchmarks rather than selftests.',
3512
3586
Option('lsprof-timed',
3513
3587
help='Generate lsprof output for benchmarked'
3514
3588
' sections of code.'),
3515
3589
Option('lsprof-tests',
3516
3590
help='Generate lsprof output for each test.'),
3517
Option('cache-dir', type=str,
3518
help='Cache intermediate benchmark output in this '
3520
3591
Option('first',
3521
3592
help='Run all tests, but run specified tests first.',
3522
3593
short_name='f',
3557
3628
def run(self, testspecs_list=None, verbose=False, one=False,
3558
3629
transport=None, benchmark=None,
3559
lsprof_timed=None, cache_dir=None,
3560
3631
first=False, list_only=False,
3561
3632
randomize=None, exclude=None, strict=False,
3562
3633
load_list=None, debugflag=None, starting_with=None, subunit=False,
3563
3634
parallel=None, lsprof_tests=False):
3564
from bzrlib.tests import selftest
3565
import bzrlib.benchmarks as benchmarks
3566
from bzrlib.benchmarks import tree_creator
3568
# Make deprecation warnings visible, unless -Werror is set
3569
symbol_versioning.activate_deprecation_warnings(override=False)
3571
if cache_dir is not None:
3572
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3635
from bzrlib import tests
3573
3637
if testspecs_list is not None:
3574
3638
pattern = '|'.join(testspecs_list)
3581
3645
raise errors.BzrCommandError("subunit not available. subunit "
3582
3646
"needs to be installed to use --subunit.")
3583
3647
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3648
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3649
# 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):
3656
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3585
3658
self.additional_selftest_args.setdefault(
3586
3659
'suite_decorators', []).append(parallel)
3588
test_suite_factory = benchmarks.test_suite
3589
# Unless user explicitly asks for quiet, be verbose in benchmarks
3590
verbose = not is_quiet()
3591
# TODO: should possibly lock the history file...
3592
benchfile = open(".perf_history", "at", buffering=1)
3593
self.add_cleanup(benchfile.close)
3595
test_suite_factory = None
3661
raise errors.BzrCommandError(
3662
"--benchmark is no longer supported from bzr 2.2; "
3663
"use bzr-usertest instead")
3664
test_suite_factory = None
3597
3665
selftest_kwargs = {"verbose": verbose,
3598
3666
"pattern": pattern,
3599
3667
"stop_on_failure": one,
3601
3669
"test_suite_factory": test_suite_factory,
3602
3670
"lsprof_timed": lsprof_timed,
3603
3671
"lsprof_tests": lsprof_tests,
3604
"bench_history": benchfile,
3605
3672
"matching_tests_first": first,
3606
3673
"list_only": list_only,
3607
3674
"random_seed": randomize,
3612
3679
"starting_with": starting_with
3614
3681
selftest_kwargs.update(self.additional_selftest_args)
3615
result = selftest(**selftest_kwargs)
3683
# Make deprecation warnings visible, unless -Werror is set
3684
cleanup = symbol_versioning.activate_deprecation_warnings(
3687
result = tests.selftest(**selftest_kwargs)
3616
3690
return int(not result)
3619
3693
class cmd_version(Command):
3620
"""Show version of bzr."""
3694
__doc__ = """Show version of bzr."""
3622
3696
encoding_type = 'replace'
3623
3697
takes_options = [
3646
3720
class cmd_find_merge_base(Command):
3647
"""Find and print a base revision for merging two branches."""
3721
__doc__ = """Find and print a base revision for merging two branches."""
3648
3722
# TODO: Options to specify revisions on either side, as if
3649
3723
# merging only part of the history.
3650
3724
takes_args = ['branch', 'other']
3657
3731
branch1 = Branch.open_containing(branch)[0]
3658
3732
branch2 = Branch.open_containing(other)[0]
3660
self.add_cleanup(branch1.unlock)
3662
self.add_cleanup(branch2.unlock)
3733
self.add_cleanup(branch1.lock_read().unlock)
3734
self.add_cleanup(branch2.lock_read().unlock)
3663
3735
last1 = ensure_null(branch1.last_revision())
3664
3736
last2 = ensure_null(branch2.last_revision())
3672
3744
class cmd_merge(Command):
3673
"""Perform a three-way merge.
3745
__doc__ = """Perform a three-way merge.
3675
3747
The source of the merge can be specified either in the form of a branch,
3676
3748
or in the form of a path to a file containing a merge directive generated
3677
3749
with bzr send. If neither is specified, the default is the upstream branch
3678
3750
or the branch most recently merged using --remember.
3680
When merging a branch, by default the tip will be merged. To pick a different
3681
revision, pass --revision. If you specify two values, the first will be used as
3682
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3683
available revisions, like this is commonly referred to as "cherrypicking".
3685
Revision numbers are always relative to the branch being merged.
3687
By default, bzr will try to merge in all new work from the other
3688
branch, automatically determining an appropriate base. If this
3689
fails, you may need to give an explicit base.
3752
When merging from a branch, by default bzr will try to merge in all new
3753
work from the other branch, automatically determining an appropriate base
3754
revision. If this fails, you may need to give an explicit base.
3756
To pick a different ending revision, pass "--revision OTHER". bzr will
3757
try to merge in all new work up to and including revision OTHER.
3759
If you specify two values, "--revision BASE..OTHER", only revisions BASE
3760
through OTHER, excluding BASE but including OTHER, will be merged. If this
3761
causes some revisions to be skipped, i.e. if the destination branch does
3762
not already contain revision BASE, such a merge is commonly referred to as
3765
Revision numbers are always relative to the source branch.
3691
3767
Merge will do its best to combine the changes in two branches, but there
3692
3768
are some kinds of problems only a human can fix. When it encounters those,
3759
3835
' completely merged into the source, pull from the'
3760
3836
' source rather than merging. When this happens,'
3761
3837
' you do not need to commit the result.'),
3838
custom_help('directory',
3763
3839
help='Branch to merge into, '
3764
'rather than the one containing the working directory.',
3840
'rather than the one containing the working directory.'),
3768
3841
Option('preview', help='Instead of merging, show a diff of the'
3770
3843
Option('interactive', help='Select changes interactively.',
3803
3876
unversioned_filter=tree.is_ignored, view_info=view_info)
3804
3877
pb = ui.ui_factory.nested_progress_bar()
3805
3878
self.add_cleanup(pb.finished)
3807
self.add_cleanup(tree.unlock)
3879
self.add_cleanup(tree.lock_write().unlock)
3808
3880
if location is not None:
3810
3882
mergeable = bundle.read_mergeable_from_url(location,
3871
3943
def _do_preview(self, merger):
3872
3944
from bzrlib.diff import show_diff_trees
3873
3945
result_tree = self._get_preview(merger)
3946
path_encoding = osutils.get_diff_header_encoding()
3874
3947
show_diff_trees(merger.this_tree, result_tree, self.outf,
3875
old_label='', new_label='')
3948
old_label='', new_label='',
3949
path_encoding=path_encoding)
3877
3951
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3878
3952
merger.change_reporter = change_reporter
3958
4032
if ((remember or tree.branch.get_submit_branch() is None) and
3959
4033
user_location is not None):
3960
4034
tree.branch.set_submit_branch(other_branch.base)
3961
_merge_tags_if_possible(other_branch, tree.branch)
4035
# Merge tags (but don't set them in the master branch yet, the user
4036
# might revert this merge). Commit will propagate them.
4037
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3962
4038
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3963
4039
other_revision_id, base_revision_id, other_branch, base_branch)
3964
4040
if other_path != '':
4063
4139
def run(self, file_list=None, merge_type=None, show_base=False,
4064
4140
reprocess=False):
4141
from bzrlib.conflicts import restore
4065
4142
if merge_type is None:
4066
4143
merge_type = _mod_merge.Merge3Merger
4067
tree, file_list = tree_files(file_list)
4069
self.add_cleanup(tree.unlock)
4144
tree, file_list = WorkingTree.open_containing_paths(file_list)
4145
self.add_cleanup(tree.lock_write().unlock)
4070
4146
parents = tree.get_parent_ids()
4071
4147
if len(parents) != 2:
4072
4148
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4127
4203
class cmd_revert(Command):
4128
"""Revert files to a previous revision.
4204
__doc__ = """Revert files to a previous revision.
4130
4206
Giving a list of files will revert only those files. Otherwise, all files
4131
4207
will be reverted. If the revision is not specified with '--revision', the
4182
4258
def run(self, revision=None, no_backup=False, file_list=None,
4183
4259
forget_merges=None):
4184
tree, file_list = tree_files(file_list)
4186
self.add_cleanup(tree.unlock)
4260
tree, file_list = WorkingTree.open_containing_paths(file_list)
4261
self.add_cleanup(tree.lock_tree_write().unlock)
4187
4262
if forget_merges:
4188
4263
tree.set_parent_ids(tree.get_parent_ids()[:1])
4305
4381
theirs_only=False,
4306
4382
log_format=None, long=False, short=False, line=False,
4307
4383
show_ids=False, verbose=False, this=False, other=False,
4308
include_merges=False, revision=None, my_revision=None):
4384
include_merges=False, revision=None, my_revision=None,
4309
4386
from bzrlib.missing import find_unmerged, iter_log_revisions
4310
4387
def message(s):
4311
4388
if not is_quiet():
4339
4418
remote_branch = Branch.open(other_branch)
4340
4419
if remote_branch.base == local_branch.base:
4341
4420
remote_branch = local_branch
4422
self.add_cleanup(remote_branch.lock_read().unlock)
4343
local_branch.lock_read()
4344
self.add_cleanup(local_branch.unlock)
4345
4424
local_revid_range = _revision_range_to_revid_range(
4346
4425
_get_revision_range(my_revision, local_branch,
4349
remote_branch.lock_read()
4350
self.add_cleanup(remote_branch.unlock)
4351
4428
remote_revid_range = _revision_range_to_revid_range(
4352
4429
_get_revision_range(revision,
4353
4430
remote_branch, self.name()))
4403
4480
message("Branches are up to date.\n")
4404
4481
self.cleanup_now()
4405
4482
if not status_code and parent is None and other_branch is not None:
4406
local_branch.lock_write()
4407
self.add_cleanup(local_branch.unlock)
4483
self.add_cleanup(local_branch.lock_write().unlock)
4408
4484
# handle race conditions - a parent might be set while we run.
4409
4485
if local_branch.get_parent() is None:
4410
4486
local_branch.set_parent(remote_branch.base)
4414
4490
class cmd_pack(Command):
4415
"""Compress the data within a repository."""
4491
__doc__ = """Compress the data within a repository.
4493
This operation compresses the data within a bazaar repository. As
4494
bazaar supports automatic packing of repository, this operation is
4495
normally not required to be done manually.
4497
During the pack operation, bazaar takes a backup of existing repository
4498
data, i.e. pack files. This backup is eventually removed by bazaar
4499
automatically when it is safe to do so. To save disk space by removing
4500
the backed up pack files, the --clean-obsolete-packs option may be
4503
Warning: If you use --clean-obsolete-packs and your machine crashes
4504
during or immediately after repacking, you may be left with a state
4505
where the deletion has been written to disk but the new packs have not
4506
been. In this case the repository may be unusable.
4417
4509
_see_also = ['repositories']
4418
4510
takes_args = ['branch_or_repo?']
4512
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4420
def run(self, branch_or_repo='.'):
4515
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4421
4516
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4423
4518
branch = dir.open_branch()
4424
4519
repository = branch.repository
4425
4520
except errors.NotBranchError:
4426
4521
repository = dir.open_repository()
4522
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4430
4525
class cmd_plugins(Command):
4431
"""List the installed plugins.
4526
__doc__ = """List the installed plugins.
4433
4528
This command displays the list of installed plugins including
4434
4529
version of plugin and a short description of each.
4522
4616
Option('long', help='Show commit date in annotations.'),
4526
4621
encoding_type = 'exact'
4528
4623
@display_command
4529
4624
def run(self, filename, all=False, long=False, revision=None,
4625
show_ids=False, directory=None):
4531
4626
from bzrlib.annotate import annotate_file, annotate_file_tree
4532
4627
wt, branch, relpath = \
4533
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4628
_open_directory_or_containing_tree_or_branch(filename, directory)
4534
4629
if wt is not None:
4536
self.add_cleanup(wt.unlock)
4630
self.add_cleanup(wt.lock_read().unlock)
4539
self.add_cleanup(branch.unlock)
4632
self.add_cleanup(branch.lock_read().unlock)
4540
4633
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4542
self.add_cleanup(tree.unlock)
4634
self.add_cleanup(tree.lock_read().unlock)
4543
4635
if wt is not None:
4544
4636
file_id = wt.path2id(relpath)
4560
4652
class cmd_re_sign(Command):
4561
"""Create a digital signature for an existing revision."""
4653
__doc__ = """Create a digital signature for an existing revision."""
4562
4654
# TODO be able to replace existing ones.
4564
4656
hidden = True # is this right ?
4565
4657
takes_args = ['revision_id*']
4566
takes_options = ['revision']
4658
takes_options = ['directory', 'revision']
4568
def run(self, revision_id_list=None, revision=None):
4660
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4569
4661
if revision_id_list is not None and revision is not None:
4570
4662
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4571
4663
if revision_id_list is None and revision is None:
4572
4664
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4573
b = WorkingTree.open_containing(u'.')[0].branch
4575
self.add_cleanup(b.unlock)
4665
b = WorkingTree.open_containing(directory)[0].branch
4666
self.add_cleanup(b.lock_write().unlock)
4576
4667
return self._run(b, revision_id_list, revision)
4578
4669
def _run(self, b, revision_id_list, revision):
4626
4717
class cmd_bind(Command):
4627
"""Convert the current branch into a checkout of the supplied branch.
4718
__doc__ = """Convert the current branch into a checkout of the supplied branch.
4719
If no branch is supplied, rebind to the last bound location.
4629
4721
Once converted into a checkout, commits must succeed on the master branch
4630
4722
before they will be applied to the local branch.
4637
4729
_see_also = ['checkouts', 'unbind']
4638
4730
takes_args = ['location?']
4731
takes_options = ['directory']
4641
def run(self, location=None):
4642
b, relpath = Branch.open_containing(u'.')
4733
def run(self, location=None, directory=u'.'):
4734
b, relpath = Branch.open_containing(directory)
4643
4735
if location is None:
4645
4737
location = b.get_old_bound_location()
4673
4765
_see_also = ['checkouts', 'bind']
4674
4766
takes_args = []
4767
takes_options = ['directory']
4678
b, relpath = Branch.open_containing(u'.')
4769
def run(self, directory=u'.'):
4770
b, relpath = Branch.open_containing(directory)
4679
4771
if not b.unbind():
4680
4772
raise errors.BzrCommandError('Local branch is not bound')
4683
4775
class cmd_uncommit(Command):
4684
"""Remove the last committed revision.
4776
__doc__ = """Remove the last committed revision.
4686
4778
--verbose will print out what is being removed.
4687
4779
--dry-run will go through all the motions, but not actually
4727
4819
b = control.open_branch()
4729
4821
if tree is not None:
4731
self.add_cleanup(tree.unlock)
4822
self.add_cleanup(tree.lock_write().unlock)
4734
self.add_cleanup(b.unlock)
4824
self.add_cleanup(b.lock_write().unlock)
4735
4825
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4737
4827
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4776
4866
self.outf.write('The above revision(s) will be removed.\n')
4779
if not ui.ui_factory.get_boolean('Are you sure'):
4780
self.outf.write('Canceled')
4869
if not ui.ui_factory.confirm_action(
4870
'Uncommit these revisions',
4871
'bzrlib.builtins.uncommit',
4873
self.outf.write('Canceled\n')
4783
4876
mutter('Uncommitting from {%s} to {%s}',
4791
4884
class cmd_break_lock(Command):
4792
"""Break a dead lock on a repository, branch or working directory.
4885
__doc__ = """Break a dead lock.
4887
This command breaks a lock on a repository, branch, working directory or
4794
4890
CAUTION: Locks should only be broken when you are sure that the process
4795
4891
holding the lock has been stopped.
4802
4898
bzr break-lock bzr+ssh://example.com/bzr/foo
4899
bzr break-lock --conf ~/.bazaar
4804
4902
takes_args = ['location?']
4905
help='LOCATION is the directory where the config lock is.'),
4907
help='Do not ask for confirmation before breaking the lock.'),
4806
def run(self, location=None, show=False):
4910
def run(self, location=None, config=False, force=False):
4807
4911
if location is None:
4808
4912
location = u'.'
4809
control, relpath = bzrdir.BzrDir.open_containing(location)
4811
control.break_lock()
4812
except NotImplementedError:
4914
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
4916
{'bzrlib.lockdir.break': True})
4918
conf = _mod_config.LockableConfig(file_name=location)
4921
control, relpath = bzrdir.BzrDir.open_containing(location)
4923
control.break_lock()
4924
except NotImplementedError:
4816
4928
class cmd_wait_until_signalled(Command):
4817
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4929
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4819
4931
This just prints a line to signal when it is ready, then blocks on stdin.
4845
4957
'result in a dynamically allocated port. The default port '
4846
4958
'depends on the protocol.',
4849
help='Serve contents of this directory.',
4960
custom_help('directory',
4961
help='Serve contents of this directory.'),
4851
4962
Option('allow-writes',
4852
4963
help='By default the server is a readonly server. Supplying '
4853
4964
'--allow-writes enables write access to the contents of '
4881
4992
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4882
4993
protocol=None):
4883
from bzrlib.transport import get_transport, transport_server_registry
4994
from bzrlib import transport
4884
4995
if directory is None:
4885
4996
directory = os.getcwd()
4886
4997
if protocol is None:
4887
protocol = transport_server_registry.get()
4998
protocol = transport.transport_server_registry.get()
4888
4999
host, port = self.get_host_and_port(port)
4889
5000
url = urlutils.local_path_to_url(directory)
4890
5001
if not allow_writes:
4891
5002
url = 'readonly+' + url
4892
transport = get_transport(url)
4893
protocol(transport, host, port, inet)
5003
t = transport.get_transport(url)
5004
protocol(t, host, port, inet)
4896
5007
class cmd_join(Command):
4897
"""Combine a tree into its containing tree.
5008
__doc__ = """Combine a tree into its containing tree.
4899
5010
This command requires the target tree to be in a rich-root format.
4902
5013
not part of it. (Such trees can be produced by "bzr split", but also by
4903
5014
running "bzr branch" with the target inside a tree.)
4905
The result is a combined tree, with the subtree no longer an independant
5016
The result is a combined tree, with the subtree no longer an independent
4906
5017
part. This is marked as a merge of the subtree into the containing tree,
4907
5018
and all history is preserved.
5007
5119
encoding_type = 'exact'
5009
5121
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
5010
sign=False, revision=None, mail_to=None, message=None):
5122
sign=False, revision=None, mail_to=None, message=None,
5011
5124
from bzrlib.revision import ensure_null, NULL_REVISION
5012
5125
include_patch, include_bundle = {
5013
5126
'plain': (False, False),
5014
5127
'diff': (True, False),
5015
5128
'bundle': (True, True),
5017
branch = Branch.open('.')
5130
branch = Branch.open(directory)
5018
5131
stored_submit_branch = branch.get_submit_branch()
5019
5132
if submit_branch is None:
5020
5133
submit_branch = stored_submit_branch
5105
5218
given, in which case it is sent to a file.
5107
5220
Mail is sent using your preferred mail program. This should be transparent
5108
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5221
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5109
5222
If the preferred client can't be found (or used), your editor will be used.
5111
5224
To use a specific mail program, set the mail_client configuration option.
5302
5412
branch, relpath = Branch.open_containing(directory)
5304
self.add_cleanup(branch.unlock)
5413
self.add_cleanup(branch.lock_write().unlock)
5306
5415
if tag_name is None:
5307
5416
raise errors.BzrCommandError("No tag specified to delete.")
5308
5417
branch.tags.delete_tag(tag_name)
5309
self.outf.write('Deleted tag %s.\n' % tag_name)
5418
note('Deleted tag %s.' % tag_name)
5312
5421
if len(revision) != 1:
5324
5433
if (not force) and branch.tags.has_tag(tag_name):
5325
5434
raise errors.TagAlreadyExists(tag_name)
5326
5435
branch.tags.set_tag(tag_name, revision_id)
5327
self.outf.write('Created tag %s.\n' % tag_name)
5436
note('Created tag %s.' % tag_name)
5330
5439
class cmd_tags(Command):
5440
__doc__ = """List tags.
5333
5442
This command shows a table of tag names and the revisions they reference.
5336
5445
_see_also = ['tag']
5337
5446
takes_options = [
5339
help='Branch whose tags should be displayed.',
5447
custom_help('directory',
5448
help='Branch whose tags should be displayed.'),
5343
5449
RegistryOption.from_kwargs('sort',
5344
5450
'Sort tags by different criteria.', title='Sorting',
5345
alpha='Sort tags lexicographically (default).',
5451
natural='Sort numeric substrings as numbers:'
5452
' suitable for version numbers. (default)',
5453
alpha='Sort tags lexicographically.',
5346
5454
time='Sort tags chronologically.',
5371
5478
# only show revisions between revid1 and revid2 (inclusive)
5372
5479
tags = [(tag, revid) for tag, revid in tags if
5373
5480
graph.is_between(revid, revid1, revid2)]
5481
if sort == 'natural':
5482
def natural_sort_key(tag):
5483
return [f(s) for f,s in
5484
zip(itertools.cycle((unicode.lower,int)),
5485
re.split('([0-9]+)', tag[0]))]
5486
tags.sort(key=natural_sort_key)
5487
elif sort == 'alpha':
5376
5489
elif sort == 'time':
5377
5490
timestamps = {}
5495
5608
class cmd_switch(Command):
5496
"""Set the branch of a checkout and update.
5609
__doc__ = """Set the branch of a checkout and update.
5498
5611
For lightweight checkouts, this changes the branch being referenced.
5499
5612
For heavyweight checkouts, this checks that there are no local commits
5518
5631
takes_args = ['to_location?']
5519
takes_options = [Option('force',
5632
takes_options = ['directory',
5520
5634
help='Switch even if local commits will be lost.'),
5522
5636
Option('create-branch', short_name='b',
5527
5641
def run(self, to_location=None, force=False, create_branch=False,
5642
revision=None, directory=u'.'):
5529
5643
from bzrlib import switch
5644
tree_location = directory
5531
5645
revision = _get_one_revision('switch', revision)
5532
5646
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5533
5647
if to_location is None:
5534
5648
if revision is None:
5535
5649
raise errors.BzrCommandError('You must supply either a'
5536
5650
' revision or a location')
5651
to_location = tree_location
5539
5653
branch = control_dir.open_branch()
5540
5654
had_explicit_nick = branch.get_config().has_explicit_nickname()
5786
5901
branch = Branch.open_containing(location)[0]
5787
5902
branch.bzrdir.destroy_branch()
5790
5905
class cmd_shelve(Command):
5791
"""Temporarily set aside some changes from the current tree.
5906
__doc__ = """Temporarily set aside some changes from the current tree.
5793
5908
Shelve allows you to temporarily put changes you've made "on the shelf",
5794
5909
ie. out of the way, until a later time when you can bring them back from
5811
5926
You can put multiple items on the shelf, and by default, 'unshelve' will
5812
5927
restore the most recently shelved changes.
5929
For complicated changes, it is possible to edit the changes in a separate
5930
editor program to decide what the file remaining in the working copy
5931
should look like. To do this, add the configuration option
5933
change_editor = PROGRAM @new_path @old_path
5935
where @new_path is replaced with the path of the new version of the
5936
file and @old_path is replaced with the path of the old version of
5937
the file. The PROGRAM should save the new file with the desired
5938
contents of the file in the working tree.
5815
5942
takes_args = ['file*']
5817
5944
takes_options = [
5819
5947
Option('all', help='Shelve all changes.'),
5826
5954
Option('destroy',
5827
5955
help='Destroy removed changes instead of shelving them.'),
5829
_see_also = ['unshelve']
5957
_see_also = ['unshelve', 'configuration']
5831
5959
def run(self, revision=None, all=False, file_list=None, message=None,
5832
writer=None, list=False, destroy=False):
5960
writer=None, list=False, destroy=False, directory=None):
5834
return self.run_for_list()
5962
return self.run_for_list(directory=directory)
5835
5963
from bzrlib.shelf_ui import Shelver
5836
5964
if writer is None:
5837
5965
writer = bzrlib.option.diff_writer_registry.get()
5839
5967
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5840
file_list, message, destroy=destroy)
5968
file_list, message, destroy=destroy, directory=directory)
5845
5973
except errors.UserAbort:
5848
def run_for_list(self):
5849
tree = WorkingTree.open_containing('.')[0]
5851
self.add_cleanup(tree.unlock)
5976
def run_for_list(self, directory=None):
5977
if directory is None:
5979
tree = WorkingTree.open_containing(directory)[0]
5980
self.add_cleanup(tree.lock_read().unlock)
5852
5981
manager = tree.get_shelf_manager()
5853
5982
shelves = manager.active_shelves()
5854
5983
if len(shelves) == 0:
5886
6016
_see_also = ['shelve']
5888
def run(self, shelf_id=None, action='apply'):
6018
def run(self, shelf_id=None, action='apply', directory=u'.'):
5889
6019
from bzrlib.shelf_ui import Unshelver
5890
unshelver = Unshelver.from_args(shelf_id, action)
6020
unshelver = Unshelver.from_args(shelf_id, action, directory=directory)
5892
6022
unshelver.run()
5910
6040
To check what clean-tree will do, use --dry-run.
5912
takes_options = [Option('ignored', help='Delete all ignored files.'),
6042
takes_options = ['directory',
6043
Option('ignored', help='Delete all ignored files.'),
5913
6044
Option('detritus', help='Delete conflict files, merge'
5914
6045
' backups, and failed selftest dirs.'),
5915
6046
Option('unknown',
5918
6049
' deleting them.'),
5919
6050
Option('force', help='Do not prompt before deleting.')]
5920
6051
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6052
force=False, directory=u'.'):
5922
6053
from bzrlib.clean_tree import clean_tree
5923
6054
if not (unknown or ignored or detritus):
5927
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5928
dry_run=dry_run, no_prompt=force)
6058
clean_tree(directory, unknown=unknown, ignored=ignored,
6059
detritus=detritus, dry_run=dry_run, no_prompt=force)
5931
6062
class cmd_reference(Command):
5932
"""list, view and set branch locations for nested trees.
6063
__doc__ = """list, view and set branch locations for nested trees.
5934
6065
If no arguments are provided, lists the branch locations for nested trees.
5935
6066
If one argument is provided, display the branch location for that tree.
5975
6106
self.outf.write('%s %s\n' % (path, location))
5978
from bzrlib.cmd_version_info import cmd_version_info
5979
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5980
from bzrlib.foreign import cmd_dpush
5981
from bzrlib.sign_my_commits import cmd_sign_my_commits
6109
def _register_lazy_builtins():
6110
# register lazy builtins from other modules; called at startup and should
6111
# be only called once.
6112
for (name, aliases, module_name) in [
6113
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6114
('cmd_config', [], 'bzrlib.config'),
6115
('cmd_dpush', [], 'bzrlib.foreign'),
6116
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6117
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6118
('cmd_conflicts', [], 'bzrlib.conflicts'),
6119
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6120
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6122
builtin_command_registry.register_lazy(name, aliases, module_name)