46
45
revision as _mod_revision,
55
54
from bzrlib.branch import Branch
56
55
from bzrlib.conflicts import ConflictList
56
from bzrlib.transport import memory
57
57
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
58
from bzrlib.smtp_connection import SMTPConnection
59
59
from bzrlib.workingtree import WorkingTree
62
from bzrlib.commands import Command, display_command
62
from bzrlib.commands import (
64
builtin_command_registry,
63
67
from bzrlib.option import (
68
72
_parse_revision_str,
70
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
80
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
73
81
def tree_files(file_list, default_branch=u'.', canonicalize=True,
76
return internal_tree_files(file_list, default_branch, canonicalize,
78
except errors.FileInWrongBranch, e:
79
raise errors.BzrCommandError("%s is not in the same branch as %s" %
80
(e.path, file_list[0]))
83
return internal_tree_files(file_list, default_branch, canonicalize,
83
87
def tree_files_for_add(file_list):
167
174
:return: workingtree, [relative_paths]
169
if file_list is None or len(file_list) == 0:
170
tree = WorkingTree.open_containing(default_branch)[0]
171
if tree.supports_views() and apply_view:
172
view_files = tree.views.lookup_view()
174
file_list = view_files
175
view_str = views.view_display_str(view_files)
176
note("Ignoring files outside view. View is %s" % view_str)
177
return tree, file_list
178
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
179
return tree, safe_relpath_files(tree, file_list, canonicalize,
180
apply_view=apply_view)
183
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
184
"""Convert file_list into a list of relpaths in tree.
186
:param tree: A tree to operate on.
187
:param file_list: A list of user provided paths or None.
188
:param apply_view: if True and a view is set, apply it or check that
189
specified files are within it
190
:return: A list of relative paths.
191
:raises errors.PathNotChild: When a provided path is in a different tree
194
if file_list is None:
196
if tree.supports_views() and apply_view:
197
view_files = tree.views.lookup_view()
201
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
202
# doesn't - fix that up here before we enter the loop.
204
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
207
for filename in file_list:
209
relpath = fixer(osutils.dereference_path(filename))
210
if view_files and not osutils.is_inside_any(view_files, relpath):
211
raise errors.FileOutsideView(filename, view_files)
212
new_list.append(relpath)
213
except errors.PathNotChild:
214
raise errors.FileInWrongBranch(tree.branch, filename)
176
return WorkingTree.open_containing_paths(
177
file_list, default_directory='.',
218
182
def _get_view_info_for_change_reporter(tree):
261
233
Not versioned and not matching an ignore pattern.
263
Additionally for directories, symlinks and files with an executable
264
bit, Bazaar indicates their type using a trailing character: '/', '@'
235
Additionally for directories, symlinks and files with a changed
236
executable bit, Bazaar indicates their type using a trailing
237
character: '/', '@' or '*' respectively. These decorations can be
238
disabled using the '--no-classify' option.
267
240
To see ignored files use 'bzr ignored'. For details on the
268
241
changes to file texts, use 'bzr diff'.
281
254
To skip the display of pending merge information altogether, use
282
255
the no-pending option or specify a file/directory.
284
If a revision argument is given, the status is calculated against
285
that revision, or between two revisions if two are provided.
257
To compare the working directory to a specific revision, pass a
258
single revision to the revision argument.
260
To see which files have changed in a specific revision, or between
261
two revisions, pass a revision range to the revision argument.
262
This will produce the same results as calling 'bzr diff --summarize'.
288
265
# TODO: --no-recurse, --recurse options
305
285
def run(self, show_ids=False, file_list=None, revision=None, short=False,
306
versioned=False, no_pending=False, verbose=False):
286
versioned=False, no_pending=False, verbose=False,
307
288
from bzrlib.status import show_tree_status
309
290
if revision and len(revision) > 2:
310
291
raise errors.BzrCommandError('bzr status --revision takes exactly'
311
292
' one or two revision specifiers')
313
tree, relfile_list = tree_files(file_list)
294
tree, relfile_list = WorkingTree.open_containing_paths(file_list)
314
295
# Avoid asking for specific files when that is not needed.
315
296
if relfile_list == ['']:
316
297
relfile_list = None
323
304
show_tree_status(tree, show_ids=show_ids,
324
305
specific_files=relfile_list, revision=revision,
325
306
to_file=self.outf, short=short, versioned=versioned,
326
show_pending=(not no_pending), verbose=verbose)
307
show_pending=(not no_pending), verbose=verbose,
308
classify=not no_classify)
329
311
class cmd_cat_revision(Command):
330
"""Write out metadata for a revision.
312
__doc__ = """Write out metadata for a revision.
332
314
The revision to print can either be specified by a specific
333
315
revision identifier, or you can use --revision.
337
319
takes_args = ['revision_id?']
338
takes_options = ['revision']
320
takes_options = ['directory', 'revision']
339
321
# cat-revision is more for frontends so should be exact
340
322
encoding = 'strict'
324
def print_revision(self, revisions, revid):
325
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
326
record = stream.next()
327
if record.storage_kind == 'absent':
328
raise errors.NoSuchRevision(revisions, revid)
329
revtext = record.get_bytes_as('fulltext')
330
self.outf.write(revtext.decode('utf-8'))
343
def run(self, revision_id=None, revision=None):
333
def run(self, revision_id=None, revision=None, directory=u'.'):
344
334
if revision_id is not None and revision is not None:
345
335
raise errors.BzrCommandError('You can only supply one of'
346
336
' revision_id or --revision')
347
337
if revision_id is None and revision is None:
348
338
raise errors.BzrCommandError('You must supply either'
349
339
' --revision or a revision_id')
350
b = WorkingTree.open_containing(u'.')[0].branch
352
# TODO: jam 20060112 should cat-revision always output utf-8?
353
if revision_id is not None:
354
revision_id = osutils.safe_revision_id(revision_id, warn=False)
356
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
357
except errors.NoSuchRevision:
358
msg = "The repository %s contains no revision %s." % (b.repository.base,
360
raise errors.BzrCommandError(msg)
361
elif revision is not None:
364
raise errors.BzrCommandError('You cannot specify a NULL'
366
rev_id = rev.as_revision_id(b)
367
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
341
b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
343
revisions = b.repository.revisions
344
if revisions is None:
345
raise errors.BzrCommandError('Repository %r does not support '
346
'access to raw revision texts')
348
b.repository.lock_read()
350
# TODO: jam 20060112 should cat-revision always output utf-8?
351
if revision_id is not None:
352
revision_id = osutils.safe_revision_id(revision_id, warn=False)
354
self.print_revision(revisions, revision_id)
355
except errors.NoSuchRevision:
356
msg = "The repository %s contains no revision %s." % (
357
b.repository.base, revision_id)
358
raise errors.BzrCommandError(msg)
359
elif revision is not None:
362
raise errors.BzrCommandError(
363
'You cannot specify a NULL revision.')
364
rev_id = rev.as_revision_id(b)
365
self.print_revision(revisions, rev_id)
367
b.repository.unlock()
370
370
class cmd_dump_btree(Command):
371
"""Dump the contents of a btree index file to stdout.
371
__doc__ = """Dump the contents of a btree index file to stdout.
373
373
PATH is a btree index file, it can be any URL. This includes things like
374
374
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
438
441
for node in bt.iter_all_entries():
439
442
# Node is made up of:
440
443
# (index, key, value, [references])
441
refs_as_tuples = static_tuple.as_tuples(node[3])
447
refs_as_tuples = None
449
refs_as_tuples = static_tuple.as_tuples(refs)
442
450
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
443
451
self.outf.write('%s\n' % (as_tuple,))
446
454
class cmd_remove_tree(Command):
447
"""Remove the working tree from a given branch/checkout.
455
__doc__ = """Remove the working tree from a given branch/checkout.
449
457
Since a lightweight checkout is little more than a working tree
450
458
this will refuse to run against one.
452
460
To re-create the working tree, use "bzr checkout".
454
462
_see_also = ['checkout', 'working-trees']
455
takes_args = ['location?']
463
takes_args = ['location*']
456
464
takes_options = [
458
466
help='Remove the working tree even if it has '
459
'uncommitted changes.'),
467
'uncommitted or shelved changes.'),
462
def run(self, location='.', force=False):
463
d = bzrdir.BzrDir.open(location)
470
def run(self, location_list, force=False):
471
if not location_list:
474
for location in location_list:
475
d = bzrdir.BzrDir.open(location)
478
working = d.open_workingtree()
479
except errors.NoWorkingTree:
480
raise errors.BzrCommandError("No working tree to remove")
481
except errors.NotLocalUrl:
482
raise errors.BzrCommandError("You cannot remove the working tree"
485
if (working.has_changes()):
486
raise errors.UncommittedChanges(working)
487
if working.get_shelf_manager().last_shelf() is not None:
488
raise errors.ShelvedChanges(working)
490
if working.user_url != working.branch.user_url:
491
raise errors.BzrCommandError("You cannot remove the working tree"
492
" from a lightweight checkout")
494
d.destroy_workingtree()
497
class cmd_repair_workingtree(Command):
498
__doc__ = """Reset the working tree state file.
500
This is not meant to be used normally, but more as a way to recover from
501
filesystem corruption, etc. This rebuilds the working inventory back to a
502
'known good' state. Any new modifications (adding a file, renaming, etc)
503
will be lost, though modified files will still be detected as such.
505
Most users will want something more like "bzr revert" or "bzr update"
506
unless the state file has become corrupted.
508
By default this attempts to recover the current state by looking at the
509
headers of the state file. If the state file is too corrupted to even do
510
that, you can supply --revision to force the state of the tree.
513
takes_options = ['revision', 'directory',
515
help='Reset the tree even if it doesn\'t appear to be'
520
def run(self, revision=None, directory='.', force=False):
521
tree, _ = WorkingTree.open_containing(directory)
522
self.add_cleanup(tree.lock_tree_write().unlock)
526
except errors.BzrError:
527
pass # There seems to be a real error here, so we'll reset
530
raise errors.BzrCommandError(
531
'The tree does not appear to be corrupt. You probably'
532
' want "bzr revert" instead. Use "--force" if you are'
533
' sure you want to reset the working tree.')
537
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
466
working = d.open_workingtree()
467
except errors.NoWorkingTree:
468
raise errors.BzrCommandError("No working tree to remove")
469
except errors.NotLocalUrl:
470
raise errors.BzrCommandError("You cannot remove the working tree"
473
if (working.has_changes()):
474
raise errors.UncommittedChanges(working)
476
working_path = working.bzrdir.root_transport.base
477
branch_path = working.branch.bzrdir.root_transport.base
478
if working_path != branch_path:
479
raise errors.BzrCommandError("You cannot remove the working tree"
480
" from a lightweight checkout")
482
d.destroy_workingtree()
539
tree.reset_state(revision_ids)
540
except errors.BzrError, e:
541
if revision_ids is None:
542
extra = (', the header appears corrupt, try passing -r -1'
543
' to set the state to the last commit')
546
raise errors.BzrCommandError('failed to reset the tree state'
485
550
class cmd_revno(Command):
486
"""Show current revision number.
551
__doc__ = """Show current revision number.
488
553
This is equal to the number of revisions on this branch.
511
575
revno = ".".join(str(n) for n in revno_t)
513
577
b = Branch.open_containing(location)[0]
515
self.add_cleanup(b.unlock)
578
self.add_cleanup(b.lock_read().unlock)
516
579
revno = b.revno()
517
580
self.cleanup_now()
518
581
self.outf.write(str(revno) + '\n')
521
584
class cmd_revision_info(Command):
522
"""Show revision number and revision id for a given revision identifier.
585
__doc__ = """Show revision number and revision id for a given revision identifier.
525
588
takes_args = ['revision_info*']
526
589
takes_options = [
591
custom_help('directory',
529
592
help='Branch to examine, '
530
'rather than the one containing the working directory.',
593
'rather than the one containing the working directory.'),
534
594
Option('tree', help='Show revno of working tree'),
811
871
raise errors.BzrCommandError('--after cannot be specified with'
813
work_tree, file_list = tree_files(names_list, default_branch='.')
814
work_tree.lock_tree_write()
815
self.add_cleanup(work_tree.unlock)
873
work_tree, file_list = WorkingTree.open_containing_paths(
874
names_list, default_directory='.')
875
self.add_cleanup(work_tree.lock_tree_write().unlock)
816
876
rename_map.RenameMap.guess_renames(work_tree, dry_run)
818
878
def _run(self, tree, names_list, rel_names, after):
912
972
match the remote one, use pull --overwrite. This will work even if the two
913
973
branches have diverged.
915
If there is no default location set, the first pull will set it. After
916
that, you can omit the location to use the default. To change the
917
default, use --remember. The value will only be saved if the remote
918
location can be accessed.
975
If there is no default location set, the first pull will set it (use
976
--no-remember to avoid settting it). After that, you can omit the
977
location to use the default. To change the default, use --remember. The
978
value will only be saved if the remote location can be accessed.
920
980
Note: The location can be specified either in the form of a branch,
921
981
or in the form of a path to a file containing a merge directive generated
926
986
takes_options = ['remember', 'overwrite', 'revision',
927
987
custom_help('verbose',
928
988
help='Show logs of pulled revisions.'),
989
custom_help('directory',
930
990
help='Branch to pull into, '
931
'rather than the one containing the working directory.',
991
'rather than the one containing the working directory.'),
936
993
help="Perform a local pull in a bound "
937
994
"branch. Local pulls are not applied to "
938
995
"the master branch."
998
help="Show base revision text in conflicts.")
941
1000
takes_args = ['location?']
942
1001
encoding_type = 'replace'
944
def run(self, location=None, remember=False, overwrite=False,
1003
def run(self, location=None, remember=None, overwrite=False,
945
1004
revision=None, verbose=False,
946
directory=None, local=False):
1005
directory=None, local=False,
947
1007
# FIXME: too much stuff is in the command class
948
1008
revision_id = None
949
1009
mergeable = None
992
1057
branch_from = Branch.open(location,
993
1058
possible_transports=possible_transports)
995
if branch_to.get_parent() is None or remember:
1059
self.add_cleanup(branch_from.lock_read().unlock)
1060
# Remembers if asked explicitly or no previous location is set
1062
or (remember is None and branch_to.get_parent() is None)):
996
1063
branch_to.set_parent(branch_from.base)
998
if branch_from is not branch_to:
999
branch_from.lock_read()
1000
self.add_cleanup(branch_from.unlock)
1001
1065
if revision is not None:
1002
1066
revision_id = revision.as_revision_id(branch_from)
1004
branch_to.lock_write()
1005
self.add_cleanup(branch_to.unlock)
1006
1068
if tree_to is not None:
1007
1069
view_info = _get_view_info_for_change_reporter(tree_to)
1008
1070
change_reporter = delta._ChangeReporter(
1042
1109
do a merge (see bzr help merge) from the other branch, and commit that.
1043
1110
After that you will be able to do a push without '--overwrite'.
1045
If there is no default push location set, the first push will set it.
1046
After that, you can omit the location to use the default. To change the
1047
default, use --remember. The value will only be saved if the remote
1048
location can be accessed.
1112
If there is no default push location set, the first push will set it (use
1113
--no-remember to avoid settting it). After that, you can omit the
1114
location to use the default. To change the default, use --remember. The
1115
value will only be saved if the remote location can be accessed.
1051
1118
_see_also = ['pull', 'update', 'working-trees']
1075
1139
Option('strict',
1076
1140
help='Refuse to push if there are uncommitted changes in'
1077
1141
' the working tree, --no-strict disables the check.'),
1143
help="Don't populate the working tree, even for protocols"
1144
" that support it."),
1079
1146
takes_args = ['location?']
1080
1147
encoding_type = 'replace'
1082
def run(self, location=None, remember=False, overwrite=False,
1149
def run(self, location=None, remember=None, overwrite=False,
1083
1150
create_prefix=False, verbose=False, revision=None,
1084
1151
use_existing_dir=False, directory=None, stacked_on=None,
1085
stacked=False, strict=None):
1152
stacked=False, strict=None, no_tree=False):
1086
1153
from bzrlib.push import _show_push_branch
1088
1155
if directory is None:
1090
1157
# Get the source branch
1091
1158
(tree, br_from,
1092
1159
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1096
1160
# Get the tip's revision_id
1097
1161
revision = _get_one_revision('push', revision)
1098
1162
if revision is not None:
1099
1163
revision_id = revision.in_history(br_from).rev_id
1101
1165
revision_id = None
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
tree, more='Use --no-strict to force the push.')
1166
if tree is not None and revision_id is None:
1167
tree.check_changed_or_out_of_date(
1168
strict, 'push_strict',
1169
more_error='Use --no-strict to force the push.',
1170
more_warning='Uncommitted changes will not be pushed.')
1113
1171
# Get the stacked_on branch, if any
1114
1172
if stacked_on is not None:
1115
1173
stacked_on = urlutils.normalize_url(stacked_on)
1138
1196
display_url = urlutils.unescape_for_display(stored_loc,
1139
1197
self.outf.encoding)
1140
self.outf.write("Using saved push location: %s\n" % display_url)
1198
note("Using saved push location: %s" % display_url)
1141
1199
location = stored_loc
1143
1201
_show_push_branch(br_from, revision_id, location, self.outf,
1144
1202
verbose=verbose, overwrite=overwrite, remember=remember,
1145
1203
stacked_on=stacked_on, create_prefix=create_prefix,
1146
use_existing_dir=use_existing_dir)
1204
use_existing_dir=use_existing_dir, no_tree=no_tree)
1149
1207
class cmd_branch(Command):
1150
"""Create a new branch that is a copy of an existing branch.
1208
__doc__ = """Create a new branch that is a copy of an existing branch.
1152
1210
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1153
1211
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1159
1217
To retrieve the branch as of a particular revision, supply the --revision
1160
1218
parameter, as in "branch foo/bar -r 5".
1220
The synonyms 'clone' and 'get' for this command are deprecated.
1163
1223
_see_also = ['checkout']
1164
1224
takes_args = ['from_location', 'to_location?']
1165
takes_options = ['revision', Option('hardlink',
1166
help='Hard-link working tree files where possible.'),
1225
takes_options = ['revision',
1226
Option('hardlink', help='Hard-link working tree files where possible.'),
1227
Option('files-from', type=str,
1228
help="Get file contents from this tree."),
1167
1229
Option('no-tree',
1168
1230
help="Create a branch without a working-tree."),
1169
1231
Option('switch',
1188
1250
def run(self, from_location, to_location=None, revision=None,
1189
1251
hardlink=False, stacked=False, standalone=False, no_tree=False,
1190
use_existing_dir=False, switch=False, bind=False):
1252
use_existing_dir=False, switch=False, bind=False,
1191
1254
from bzrlib import switch as _mod_switch
1192
1255
from bzrlib.tag import _merge_tags_if_possible
1256
if self.invoked_as in ['get', 'clone']:
1257
ui.ui_factory.show_user_warning(
1258
'deprecated_command',
1259
deprecated_name=self.invoked_as,
1260
recommended_name='branch',
1261
deprecated_in_version='2.4')
1193
1262
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1264
if not (hardlink or files_from):
1265
# accelerator_tree is usually slower because you have to read N
1266
# files (no readahead, lots of seeks, etc), but allow the user to
1267
# explicitly request it
1268
accelerator_tree = None
1269
if files_from is not None and files_from != from_location:
1270
accelerator_tree = WorkingTree.open(files_from)
1195
1271
revision = _get_one_revision('branch', revision)
1197
self.add_cleanup(br_from.unlock)
1272
self.add_cleanup(br_from.lock_read().unlock)
1198
1273
if revision is not None:
1199
1274
revision_id = revision.as_revision_id(br_from)
1305
1380
to_location = branch_location
1306
1381
accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1307
1382
branch_location)
1383
if not (hardlink or files_from):
1384
# accelerator_tree is usually slower because you have to read N
1385
# files (no readahead, lots of seeks, etc), but allow the user to
1386
# explicitly request it
1387
accelerator_tree = None
1308
1388
revision = _get_one_revision('checkout', revision)
1309
if files_from is not None:
1389
if files_from is not None and files_from != branch_location:
1310
1390
accelerator_tree = WorkingTree.open(files_from)
1311
1391
if revision is not None:
1312
1392
revision_id = revision.as_revision_id(source)
1370
1448
If you want to discard your local changes, you can just do a
1371
1449
'bzr revert' instead of 'bzr commit' after the update.
1451
If you want to restore a file that has been removed locally, use
1452
'bzr revert' instead of 'bzr update'.
1373
1454
If the tree's branch is bound to a master branch, it will also update
1374
1455
the branch from the master.
1377
1458
_see_also = ['pull', 'working-trees', 'status-flags']
1378
1459
takes_args = ['dir?']
1379
takes_options = ['revision']
1460
takes_options = ['revision',
1462
help="Show base revision text in conflicts."),
1380
1464
aliases = ['up']
1382
def run(self, dir='.', revision=None):
1466
def run(self, dir='.', revision=None, show_base=None):
1383
1467
if revision is not None and len(revision) != 1:
1384
1468
raise errors.BzrCommandError(
1385
1469
"bzr update --revision takes exactly one revision")
1424
1509
change_reporter,
1425
1510
possible_transports=possible_transports,
1426
1511
revision=revision_id,
1513
show_base=show_base)
1428
1514
except errors.NoSuchRevision, e:
1429
1515
raise errors.BzrCommandError(
1430
1516
"branch has no revision %s\n"
1431
1517
"bzr update --revision only works"
1432
1518
" for a revision in the branch history"
1433
1519
% (e.revision))
1434
revno = tree.branch.revision_id_to_revno(
1520
revno = tree.branch.revision_id_to_dotted_revno(
1435
1521
_mod_revision.ensure_null(tree.last_revision()))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
if tree.get_parent_ids()[1:] != existing_pending_merges:
1522
note('Updated to revision %s of branch %s' %
1523
('.'.join(map(str, revno)), branch_location))
1524
parent_ids = tree.get_parent_ids()
1525
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1439
1526
note('Your local commits will now show as pending merges with '
1440
1527
"'bzr status', and can be committed with 'bzr commit'.")
1441
1528
if conflicts != 0:
1491
1578
class cmd_remove(Command):
1492
"""Remove files or directories.
1579
__doc__ = """Remove files or directories.
1494
This makes bzr stop tracking changes to the specified files. bzr will delete
1495
them if they can easily be recovered using revert. If no options or
1496
parameters are given bzr will scan for files that are being tracked by bzr
1497
but missing in your tree and stop tracking them for you.
1581
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1582
delete them if they can easily be recovered using revert otherwise they
1583
will be backed up (adding an extention of the form .~#~). If no options or
1584
parameters are given Bazaar will scan for files that are being tracked by
1585
Bazaar but missing in your tree and stop tracking them for you.
1499
1587
takes_args = ['file*']
1500
1588
takes_options = ['verbose',
1502
1590
RegistryOption.from_kwargs('file-deletion-strategy',
1503
1591
'The file deletion mode to be used.',
1504
1592
title='Deletion Strategy', value_switches=True, enum_switch=False,
1505
safe='Only delete files if they can be'
1506
' safely recovered (default).',
1593
safe='Backup changed files (default).',
1507
1594
keep='Delete from bzr but leave the working copy.',
1595
no_backup='Don\'t backup changed files.',
1508
1596
force='Delete all the specified files, even if they can not be '
1509
'recovered and even if they are non-empty directories.')]
1597
'recovered and even if they are non-empty directories. '
1598
'(deprecated, use no-backup)')]
1510
1599
aliases = ['rm', 'del']
1511
1600
encoding_type = 'replace'
1513
1602
def run(self, file_list, verbose=False, new=False,
1514
1603
file_deletion_strategy='safe'):
1515
tree, file_list = tree_files(file_list)
1604
if file_deletion_strategy == 'force':
1605
note("(The --force option is deprecated, rather use --no-backup "
1607
file_deletion_strategy = 'no-backup'
1609
tree, file_list = WorkingTree.open_containing_paths(file_list)
1517
1611
if file_list is not None:
1518
1612
file_list = [f for f in file_list]
1521
self.add_cleanup(tree.unlock)
1614
self.add_cleanup(tree.lock_write().unlock)
1522
1615
# Heuristics should probably all move into tree.remove_smart or
1539
1632
file_deletion_strategy = 'keep'
1540
1633
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1541
1634
keep_files=file_deletion_strategy=='keep',
1542
force=file_deletion_strategy=='force')
1635
force=(file_deletion_strategy=='no-backup'))
1545
1638
class cmd_file_id(Command):
1546
"""Print file_id of a particular file or directory.
1639
__doc__ = """Print file_id of a particular file or directory.
1548
1641
The file_id is assigned when the file is first added and remains the
1549
1642
same through all revisions where the file exists, even when it is
1608
1701
_see_also = ['check']
1609
1702
takes_args = ['branch?']
1704
Option('canonicalize-chks',
1705
help='Make sure CHKs are in canonical form (repairs '
1611
def run(self, branch="."):
1710
def run(self, branch=".", canonicalize_chks=False):
1612
1711
from bzrlib.reconcile import reconcile
1613
1712
dir = bzrdir.BzrDir.open(branch)
1713
reconcile(dir, canonicalize_chks=canonicalize_chks)
1617
1716
class cmd_revision_history(Command):
1618
"""Display the list of revision ids on a branch."""
1717
__doc__ = """Display the list of revision ids on a branch."""
1620
1719
_see_also = ['log']
1621
1720
takes_args = ['location?']
1650
1749
last_revision = wt.last_revision()
1652
revision_ids = b.repository.get_ancestry(last_revision)
1654
for revision_id in revision_ids:
1751
self.add_cleanup(b.repository.lock_read().unlock)
1752
graph = b.repository.get_graph()
1753
revisions = [revid for revid, parents in
1754
graph.iter_ancestry([last_revision])]
1755
for revision_id in reversed(revisions):
1756
if _mod_revision.is_null(revision_id):
1655
1758
self.outf.write(revision_id + '\n')
1658
1761
class cmd_init(Command):
1659
"""Make a directory into a versioned branch.
1762
__doc__ = """Make a directory into a versioned branch.
1661
1764
Use this to create an empty branch, or before importing an
1662
1765
existing project.
1917
2044
help='Use this command to compare files.',
2047
RegistryOption('format',
2049
help='Diff format to use.',
2050
lazy_registry=('bzrlib.diff', 'format_registry'),
2051
title='Diff format'),
1921
2053
aliases = ['di', 'dif']
1922
2054
encoding_type = 'exact'
1924
2056
@display_command
1925
2057
def run(self, revision=None, file_list=None, diff_options=None,
1926
prefix=None, old=None, new=None, using=None):
1927
from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
2058
prefix=None, old=None, new=None, using=None, format=None):
2059
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
1929
2062
if (prefix is None) or (prefix == '0'):
1930
2063
# diff -p0 format
1944
2077
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1945
2078
' one or two revision specifiers')
2080
if using is not None and format is not None:
2081
raise errors.BzrCommandError('--using and --format are mutually '
1947
2084
(old_tree, new_tree,
1948
2085
old_branch, new_branch,
1949
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1950
file_list, revision, old, new, apply_view=True)
2086
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2087
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2088
# GNU diff on Windows uses ANSI encoding for filenames
2089
path_encoding = osutils.get_diff_header_encoding()
1951
2090
return show_diff_trees(old_tree, new_tree, sys.stdout,
1952
2091
specific_files=specific_files,
1953
2092
external_diff_options=diff_options,
1954
2093
old_label=old_label, new_label=new_label,
1955
extra_trees=extra_trees, using=using)
2094
extra_trees=extra_trees,
2095
path_encoding=path_encoding,
1958
2100
class cmd_deleted(Command):
1959
"""List files deleted in the working tree.
2101
__doc__ = """List files deleted in the working tree.
1961
2103
# TODO: Show files deleted since a previous revision, or
1962
2104
# between two revisions.
1965
2107
# level of effort but possibly much less IO. (Or possibly not,
1966
2108
# if the directories are very large...)
1967
2109
_see_also = ['status', 'ls']
1968
takes_options = ['show-ids']
2110
takes_options = ['directory', 'show-ids']
1970
2112
@display_command
1971
def run(self, show_ids=False):
1972
tree = WorkingTree.open_containing(u'.')[0]
1974
self.add_cleanup(tree.unlock)
2113
def run(self, show_ids=False, directory=u'.'):
2114
tree = WorkingTree.open_containing(directory)[0]
2115
self.add_cleanup(tree.lock_read().unlock)
1975
2116
old = tree.basis_tree()
1977
self.add_cleanup(old.unlock)
2117
self.add_cleanup(old.lock_read().unlock)
1978
2118
for path, ie in old.inventory.iter_entries():
1979
2119
if not tree.has_id(ie.file_id):
1980
2120
self.outf.write(path)
1987
2127
class cmd_modified(Command):
1988
"""List files modified in working tree.
2128
__doc__ = """List files modified in working tree.
1992
2132
_see_also = ['status', 'ls']
1995
help='Write an ascii NUL (\\0) separator '
1996
'between files rather than a newline.')
2133
takes_options = ['directory', 'null']
1999
2135
@display_command
2000
def run(self, null=False):
2001
tree = WorkingTree.open_containing(u'.')[0]
2136
def run(self, null=False, directory=u'.'):
2137
tree = WorkingTree.open_containing(directory)[0]
2138
self.add_cleanup(tree.lock_read().unlock)
2002
2139
td = tree.changes_from(tree.basis_tree())
2003
2141
for path, id, kind, text_modified, meta_modified in td.modified:
2005
2143
self.outf.write(path + '\0')
2010
2148
class cmd_added(Command):
2011
"""List files added in working tree.
2149
__doc__ = """List files added in working tree.
2015
2153
_see_also = ['status', 'ls']
2018
help='Write an ascii NUL (\\0) separator '
2019
'between files rather than a newline.')
2154
takes_options = ['directory', 'null']
2022
2156
@display_command
2023
def run(self, null=False):
2024
wt = WorkingTree.open_containing(u'.')[0]
2026
self.add_cleanup(wt.unlock)
2157
def run(self, null=False, directory=u'.'):
2158
wt = WorkingTree.open_containing(directory)[0]
2159
self.add_cleanup(wt.lock_read().unlock)
2027
2160
basis = wt.basis_tree()
2029
self.add_cleanup(basis.unlock)
2161
self.add_cleanup(basis.lock_read().unlock)
2030
2162
basis_inv = basis.inventory
2031
2163
inv = wt.inventory
2032
2164
for file_id in inv:
2033
if file_id in basis_inv:
2165
if basis_inv.has_id(file_id):
2035
2167
if inv.is_root(file_id) and len(basis_inv) == 0:
2037
2169
path = inv.id2path(file_id)
2038
if not os.access(osutils.abspath(path), os.F_OK):
2170
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2041
2173
self.outf.write(path + '\0')
2261
2401
help='Show changes made in each revision as a patch.'),
2262
2402
Option('include-merges',
2263
2403
help='Show merged revisions like --levels 0 does.'),
2404
Option('exclude-common-ancestry',
2405
help='Display only the revisions that are not part'
2406
' of both ancestries (require -rX..Y)'
2408
Option('signatures',
2409
help='Show digital signature validity'),
2412
help='Show revisions whose properties match this '
2415
ListOption('match-message',
2416
help='Show revisions whose message matches this '
2419
ListOption('match-committer',
2420
help='Show revisions whose committer matches this '
2423
ListOption('match-author',
2424
help='Show revisions whose authors match this '
2427
ListOption('match-bugs',
2428
help='Show revisions whose bugs match this '
2265
2432
encoding_type = 'replace'
2474
2678
help='Recurse into subdirectories.'),
2475
2679
Option('from-root',
2476
2680
help='Print paths relative to the root of the branch.'),
2477
Option('unknown', help='Print unknown files.'),
2681
Option('unknown', short_name='u',
2682
help='Print unknown files.'),
2478
2683
Option('versioned', help='Print versioned files.',
2479
2684
short_name='V'),
2480
Option('ignored', help='Print ignored files.'),
2482
help='Write an ascii NUL (\\0) separator '
2483
'between files rather than a newline.'),
2685
Option('ignored', short_name='i',
2686
help='Print ignored files.'),
2687
Option('kind', short_name='k',
2485
2688
help='List entries of a particular kind: file, directory, symlink.',
2489
2694
@display_command
2490
2695
def run(self, revision=None, verbose=False,
2491
2696
recursive=False, from_root=False,
2492
2697
unknown=False, versioned=False, ignored=False,
2493
null=False, kind=None, show_ids=False, path=None):
2698
null=False, kind=None, show_ids=False, path=None, directory=None):
2495
2700
if kind and kind not in ('file', 'directory', 'symlink'):
2496
2701
raise errors.BzrCommandError('invalid kind specified')
2653
2873
_see_also = ['status', 'ignored', 'patterns']
2654
2874
takes_args = ['name_pattern*']
2656
Option('old-default-rules',
2657
help='Write out the ignore rules bzr < 0.9 always used.')
2875
takes_options = ['directory',
2876
Option('default-rules',
2877
help='Display the default ignore rules that bzr uses.')
2660
def run(self, name_pattern_list=None, old_default_rules=None):
2880
def run(self, name_pattern_list=None, default_rules=None,
2661
2882
from bzrlib import ignores
2662
if old_default_rules is not None:
2663
# dump the rules and exit
2664
for pattern in ignores.OLD_DEFAULTS:
2883
if default_rules is not None:
2884
# dump the default rules and exit
2885
for pattern in ignores.USER_DEFAULTS:
2886
self.outf.write("%s\n" % pattern)
2667
2888
if not name_pattern_list:
2668
2889
raise errors.BzrCommandError("ignore requires at least one "
2669
"NAME_PATTERN or --old-default-rules")
2890
"NAME_PATTERN or --default-rules.")
2670
2891
name_pattern_list = [globbing.normalize_pattern(p)
2671
2892
for p in name_pattern_list]
2894
for p in name_pattern_list:
2895
if not globbing.Globster.is_pattern_valid(p):
2896
bad_patterns += ('\n %s' % p)
2898
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2899
ui.ui_factory.show_error(msg)
2900
raise errors.InvalidPattern('')
2672
2901
for name_pattern in name_pattern_list:
2673
2902
if (name_pattern[0] == '/' or
2674
2903
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2675
2904
raise errors.BzrCommandError(
2676
2905
"NAME_PATTERN should not be an absolute path")
2677
tree, relpath = WorkingTree.open_containing(u'.')
2906
tree, relpath = WorkingTree.open_containing(directory)
2678
2907
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2679
2908
ignored = globbing.Globster(name_pattern_list)
2910
self.add_cleanup(tree.lock_read().unlock)
2682
2911
for entry in tree.list_files():
2684
2913
if id is not None:
2685
2914
filename = entry[0]
2686
2915
if ignored.match(filename):
2687
matches.append(filename.encode('utf-8'))
2916
matches.append(filename)
2689
2917
if len(matches) > 0:
2690
print "Warning: the following files are version controlled and" \
2691
" match your ignore pattern:\n%s" \
2692
"\nThese files will continue to be version controlled" \
2693
" unless you 'bzr remove' them." % ("\n".join(matches),)
2918
self.outf.write("Warning: the following files are version controlled and"
2919
" match your ignore pattern:\n%s"
2920
"\nThese files will continue to be version controlled"
2921
" unless you 'bzr remove' them.\n" % ("\n".join(matches),))
2696
2924
class cmd_ignored(Command):
2697
"""List ignored files and the patterns that matched them.
2925
__doc__ = """List ignored files and the patterns that matched them.
2699
2927
List all the ignored files and the ignore pattern that caused the file to
2723
2951
class cmd_lookup_revision(Command):
2724
"""Lookup the revision-id from a revision-number
2952
__doc__ = """Lookup the revision-id from a revision-number
2727
2955
bzr lookup-revision 33
2730
2958
takes_args = ['revno']
2959
takes_options = ['directory']
2732
2961
@display_command
2733
def run(self, revno):
2962
def run(self, revno, directory=u'.'):
2735
2964
revno = int(revno)
2736
2965
except ValueError:
2737
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2739
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2966
raise errors.BzrCommandError("not a valid revision-number: %r"
2968
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
2969
self.outf.write("%s\n" % revid)
2742
2972
class cmd_export(Command):
2743
"""Export current or past revision to a destination directory or archive.
2973
__doc__ = """Export current or past revision to a destination directory or archive.
2745
2975
If no revision is specified this exports the last committed revision.
2780
3011
help="Name of the root directory inside the exported file."),
3012
Option('per-file-timestamps',
3013
help='Set modification time of files to that of the last '
3014
'revision in which it was changed.'),
2782
3016
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2783
root=None, filters=False):
3017
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
2784
3018
from bzrlib.export import export
2786
3020
if branch_or_subdir is None:
2787
tree = WorkingTree.open_containing(u'.')[0]
3021
tree = WorkingTree.open_containing(directory)[0]
2788
3022
b = tree.branch
2794
3028
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2796
export(rev_tree, dest, format, root, subdir, filtered=filters)
3030
export(rev_tree, dest, format, root, subdir, filtered=filters,
3031
per_file_timestamps=per_file_timestamps)
2797
3032
except errors.NoSuchExportFormat, e:
2798
3033
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2801
3036
class cmd_cat(Command):
2802
"""Write the contents of a file as of a given revision to standard output.
3037
__doc__ = """Write the contents of a file as of a given revision to standard output.
2804
3039
If no revision is nominated, the last revision is used.
2820
3055
@display_command
2821
3056
def run(self, filename, revision=None, name_from_revision=False,
3057
filters=False, directory=None):
2823
3058
if revision is not None and len(revision) != 1:
2824
3059
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2825
3060
" one revision specifier")
2826
3061
tree, branch, relpath = \
2827
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2829
self.add_cleanup(branch.unlock)
3062
_open_directory_or_containing_tree_or_branch(filename, directory)
3063
self.add_cleanup(branch.lock_read().unlock)
2830
3064
return self._run(tree, branch, relpath, filename, revision,
2831
3065
name_from_revision, filters)
2847
3084
"%r is not present in revision %s" % (
2848
3085
filename, rev_tree.get_revision_id()))
2850
content = rev_tree.get_file_text(old_file_id)
3087
actual_file_id = old_file_id
2852
3089
cur_file_id = tree.path2id(relpath)
2854
if cur_file_id is not None:
2855
# Then try with the actual file id
2857
content = rev_tree.get_file_text(cur_file_id)
2859
except errors.NoSuchId:
2860
# The actual file id didn't exist at that time
2862
if not found and old_file_id is not None:
2863
# Finally try with the old file id
2864
content = rev_tree.get_file_text(old_file_id)
2867
# Can't be found anywhere
3090
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3091
actual_file_id = cur_file_id
3092
elif old_file_id is not None:
3093
actual_file_id = old_file_id
2868
3095
raise errors.BzrCommandError(
2869
3096
"%r is not present in revision %s" % (
2870
3097
filename, rev_tree.get_revision_id()))
2872
from bzrlib.filters import (
2873
ContentFilterContext,
2874
filtered_output_bytes,
2876
filters = rev_tree._content_filter_stack(relpath)
2877
chunks = content.splitlines(True)
2878
content = filtered_output_bytes(chunks, filters,
2879
ContentFilterContext(relpath, rev_tree))
2881
self.outf.writelines(content)
3099
from bzrlib.filter_tree import ContentFilterTree
3100
filter_tree = ContentFilterTree(rev_tree,
3101
rev_tree._content_filter_stack)
3102
content = filter_tree.get_file_text(actual_file_id)
2884
self.outf.write(content)
3104
content = rev_tree.get_file_text(actual_file_id)
3106
self.outf.write(content)
2887
3109
class cmd_local_time_offset(Command):
2888
"""Show the offset in seconds from GMT to local time."""
3110
__doc__ = """Show the offset in seconds from GMT to local time."""
2890
3112
@display_command
2892
print osutils.local_time_offset()
3114
self.outf.write("%s\n" % osutils.local_time_offset())
2896
3118
class cmd_commit(Command):
2897
"""Commit changes into a new revision.
3119
__doc__ = """Commit changes into a new revision.
2899
3121
An explanatory message needs to be given for each commit. This is
2900
3122
often done by using the --message option (getting the message from the
2948
3170
to trigger updates to external systems like bug trackers. The --fixes
2949
3171
option can be used to record the association between a revision and
2950
3172
one or more bugs. See ``bzr help bugs`` for details.
2952
A selective commit may fail in some cases where the committed
2953
tree would be invalid. Consider::
2958
bzr commit foo -m "committing foo"
2959
bzr mv foo/bar foo/baz
2962
bzr commit foo/bar -m "committing bar but not baz"
2964
In the example above, the last commit will fail by design. This gives
2965
the user the opportunity to decide whether they want to commit the
2966
rename at the same time, separately first, or not at all. (As a general
2967
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2969
# TODO: Run hooks on tree to-be-committed, and after commit.
2971
# TODO: Strict commit that fails if there are deleted files.
2972
# (what does "deleted files" mean ??)
2974
# TODO: Give better message for -s, --summary, used by tla people
2976
# XXX: verbose currently does nothing
2978
3175
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2979
3176
takes_args = ['selected*']
3055
3258
raise errors.BzrCommandError(
3056
3259
"Could not parse --commit-time: " + str(e))
3058
# TODO: Need a blackbox test for invoking the external editor; may be
3059
# slightly problematic to run this cross-platform.
3061
# TODO: do more checks that the commit will succeed before
3062
# spending the user's valuable time typing a commit message.
3064
3261
properties = {}
3066
tree, selected_list = tree_files(selected_list)
3263
tree, selected_list = WorkingTree.open_containing_paths(selected_list)
3067
3264
if selected_list == ['']:
3068
3265
# workaround - commit of root of tree should be exactly the same
3069
3266
# as just default commit in that tree, and succeed even though
3094
3291
'(use --file "%(f)s" to take commit message from that file)'
3095
3292
% { 'f': message })
3096
3293
ui.ui_factory.show_warning(warning_msg)
3295
message = message.replace('\r\n', '\n')
3296
message = message.replace('\r', '\n')
3298
raise errors.BzrCommandError(
3299
"please specify either --message or --file")
3098
3301
def get_message(commit_obj):
3099
3302
"""Callback to get commit message"""
3100
my_message = message
3101
if my_message is not None and '\r' in my_message:
3102
my_message = my_message.replace('\r\n', '\n')
3103
my_message = my_message.replace('\r', '\n')
3104
if my_message is None and not file:
3105
t = make_commit_message_template_encoded(tree,
3306
my_message = f.read().decode(osutils.get_user_encoding())
3309
elif message is not None:
3310
my_message = message
3312
# No message supplied: make one up.
3313
# text is the status of the tree
3314
text = make_commit_message_template_encoded(tree,
3106
3315
selected_list, diff=show_diff,
3107
3316
output_encoding=osutils.get_user_encoding())
3108
start_message = generate_commit_message_template(commit_obj)
3109
my_message = edit_commit_message_encoded(t,
3110
start_message=start_message)
3317
# start_message is the template generated from hooks
3318
# XXX: Warning - looks like hooks return unicode,
3319
# make_commit_message_template_encoded returns user encoding.
3320
# We probably want to be using edit_commit_message instead to
3322
my_message = set_commit_message(commit_obj)
3323
if my_message is None:
3324
start_message = generate_commit_message_template(commit_obj)
3325
my_message = edit_commit_message_encoded(text,
3326
start_message=start_message)
3111
3327
if my_message is None:
3112
3328
raise errors.BzrCommandError("please specify a commit"
3113
3329
" message with either --message or --file")
3114
elif my_message and file:
3115
raise errors.BzrCommandError(
3116
"please specify either --message or --file")
3118
my_message = codecs.open(file, 'rt',
3119
osutils.get_user_encoding()).read()
3120
3330
if my_message == "":
3121
raise errors.BzrCommandError("empty commit message specified")
3331
raise errors.BzrCommandError("Empty commit message specified."
3332
" Please specify a commit message with either"
3333
" --message or --file or leave a blank message"
3334
" with --message \"\".")
3122
3335
return my_message
3124
3337
# The API permits a commit with a filter of [] to mean 'select nothing'
3132
3345
reporter=None, verbose=verbose, revprops=properties,
3133
3346
authors=author, timestamp=commit_stamp,
3134
3347
timezone=offset,
3135
exclude=safe_relpath_files(tree, exclude))
3348
exclude=tree.safe_relpath_files(exclude),
3136
3350
except PointlessCommit:
3137
# FIXME: This should really happen before the file is read in;
3138
# perhaps prepare the commit; get the message; then actually commit
3139
3351
raise errors.BzrCommandError("No changes to commit."
3140
" Use --unchanged to commit anyhow.")
3352
" Please 'bzr add' the files you want to commit, or use"
3353
" --unchanged to force an empty commit.")
3141
3354
except ConflictsInTree:
3142
3355
raise errors.BzrCommandError('Conflicts detected in working '
3143
3356
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3146
3359
raise errors.BzrCommandError("Commit refused because there are"
3147
3360
" unknown files in the working tree.")
3148
3361
except errors.BoundBranchOutOfDate, e:
3149
raise errors.BzrCommandError(str(e) + "\n"
3150
'To commit to master branch, run update and then commit.\n'
3151
'You can also pass --local to commit to continue working '
3362
e.extra_help = ("\n"
3363
'To commit to master branch, run update and then commit.\n'
3364
'You can also pass --local to commit to continue working '
3155
3369
class cmd_check(Command):
3156
"""Validate working tree structure, branch consistency and repository history.
3370
__doc__ = """Validate working tree structure, branch consistency and repository history.
3158
3372
This command checks various invariants about branch and repository storage
3159
3373
to detect data corruption or bzr bugs.
3225
3439
class cmd_upgrade(Command):
3226
"""Upgrade branch storage to current format.
3228
The check command or bzr developers may sometimes advise you to run
3229
this command. When the default format has changed you may also be warned
3230
during other operations to upgrade.
3440
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3442
When the default format has changed after a major new release of
3443
Bazaar, you may be informed during certain operations that you
3444
should upgrade. Upgrading to a newer format may improve performance
3445
or make new features available. It may however limit interoperability
3446
with older repositories or with older versions of Bazaar.
3448
If you wish to upgrade to a particular format rather than the
3449
current default, that can be specified using the --format option.
3450
As a consequence, you can use the upgrade command this way to
3451
"downgrade" to an earlier format, though some conversions are
3452
a one way process (e.g. changing from the 1.x default to the
3453
2.x default) so downgrading is not always possible.
3455
A backup.bzr.~#~ directory is created at the start of the conversion
3456
process (where # is a number). By default, this is left there on
3457
completion. If the conversion fails, delete the new .bzr directory
3458
and rename this one back in its place. Use the --clean option to ask
3459
for the backup.bzr directory to be removed on successful conversion.
3460
Alternatively, you can delete it by hand if everything looks good
3463
If the location given is a shared repository, dependent branches
3464
are also converted provided the repository converts successfully.
3465
If the conversion of a branch fails, remaining branches are still
3468
For more information on upgrades, see the Bazaar Upgrade Guide,
3469
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3233
_see_also = ['check']
3472
_see_also = ['check', 'reconcile', 'formats']
3234
3473
takes_args = ['url?']
3235
3474
takes_options = [
3236
RegistryOption('format',
3237
help='Upgrade to a specific format. See "bzr help'
3238
' formats" for details.',
3239
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3240
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3241
value_switches=True, title='Branch format'),
3475
RegistryOption('format',
3476
help='Upgrade to a specific format. See "bzr help'
3477
' formats" for details.',
3478
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3479
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3480
value_switches=True, title='Branch format'),
3482
help='Remove the backup.bzr directory if successful.'),
3484
help="Show what would be done, but don't actually do anything."),
3244
def run(self, url='.', format=None):
3487
def run(self, url='.', format=None, clean=False, dry_run=False):
3245
3488
from bzrlib.upgrade import upgrade
3246
upgrade(url, format)
3489
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3491
if len(exceptions) == 1:
3492
# Compatibility with historical behavior
3249
3498
class cmd_whoami(Command):
3250
"""Show or set bzr user id.
3499
__doc__ = """Show or set bzr user id.
3253
3502
Show the email of the current user::
3268
3518
encoding_type = 'replace'
3270
3520
@display_command
3271
def run(self, email=False, branch=False, name=None):
3521
def run(self, email=False, branch=False, name=None, directory=None):
3272
3522
if name is None:
3273
# use branch if we're inside one; otherwise global config
3275
c = Branch.open_containing('.')[0].get_config()
3276
except errors.NotBranchError:
3277
c = config.GlobalConfig()
3523
if directory is None:
3524
# use branch if we're inside one; otherwise global config
3526
c = Branch.open_containing(u'.')[0].get_config()
3527
except errors.NotBranchError:
3528
c = _mod_config.GlobalConfig()
3530
c = Branch.open(directory).get_config()
3279
3532
self.outf.write(c.user_email() + '\n')
3281
3534
self.outf.write(c.username() + '\n')
3538
raise errors.BzrCommandError("--email can only be used to display existing "
3284
3541
# display a warning if an email address isn't included in the given name.
3286
config.extract_email_address(name)
3543
_mod_config.extract_email_address(name)
3287
3544
except errors.NoEmailInUsername, e:
3288
3545
warning('"%s" does not seem to contain an email address. '
3289
3546
'This is allowed, but not recommended.', name)
3291
3548
# use global config unless --branch given
3293
c = Branch.open_containing('.')[0].get_config()
3550
if directory is None:
3551
c = Branch.open_containing(u'.')[0].get_config()
3553
c = Branch.open(directory).get_config()
3295
c = config.GlobalConfig()
3555
c = _mod_config.GlobalConfig()
3296
3556
c.set_user_option('email', name)
3299
3559
class cmd_nick(Command):
3300
"""Print or set the branch nickname.
3560
__doc__ = """Print or set the branch nickname.
3302
3562
If unset, the tree root directory name is used as the nickname.
3303
3563
To print the current nickname, execute with no argument.
3364
3625
'bzr alias --remove expects an alias to remove.')
3365
3626
# If alias is not found, print something like:
3366
3627
# unalias: foo: not found
3367
c = config.GlobalConfig()
3628
c = _mod_config.GlobalConfig()
3368
3629
c.unset_alias(alias_name)
3370
3631
@display_command
3371
3632
def print_aliases(self):
3372
3633
"""Print out the defined aliases in a similar format to bash."""
3373
aliases = config.GlobalConfig().get_aliases()
3634
aliases = _mod_config.GlobalConfig().get_aliases()
3374
3635
for key, value in sorted(aliases.iteritems()):
3375
3636
self.outf.write('bzr alias %s="%s"\n' % (key, value))
3387
3648
def set_alias(self, alias_name, alias_command):
3388
3649
"""Save the alias in the global config."""
3389
c = config.GlobalConfig()
3650
c = _mod_config.GlobalConfig()
3390
3651
c.set_alias(alias_name, alias_command)
3393
3654
class cmd_selftest(Command):
3394
"""Run internal test suite.
3655
__doc__ = """Run internal test suite.
3396
3657
If arguments are given, they are regular expressions that say which tests
3397
3658
should run. Tests matching any expression are run, and other tests are
3443
3707
if typestring == "sftp":
3444
3708
from bzrlib.tests import stub_sftp
3445
3709
return stub_sftp.SFTPAbsoluteServer
3446
if typestring == "memory":
3447
from bzrlib.transport.memory import MemoryServer
3449
if typestring == "fakenfs":
3450
from bzrlib.transport.fakenfs import FakeNFSServer
3451
return FakeNFSServer
3710
elif typestring == "memory":
3711
from bzrlib.tests import test_server
3712
return memory.MemoryServer
3713
elif typestring == "fakenfs":
3714
from bzrlib.tests import test_server
3715
return test_server.FakeNFSServer
3452
3716
msg = "No known transport type %s. Supported types are: sftp\n" %\
3454
3718
raise errors.BzrCommandError(msg)
3465
3729
'throughout the test suite.',
3466
3730
type=get_transport_type),
3467
3731
Option('benchmark',
3468
help='Run the benchmarks rather than selftests.'),
3732
help='Run the benchmarks rather than selftests.',
3469
3734
Option('lsprof-timed',
3470
3735
help='Generate lsprof output for benchmarked'
3471
3736
' sections of code.'),
3472
3737
Option('lsprof-tests',
3473
3738
help='Generate lsprof output for each test.'),
3474
Option('cache-dir', type=str,
3475
help='Cache intermediate benchmark output in this '
3477
3739
Option('first',
3478
3740
help='Run all tests, but run specified tests first.',
3479
3741
short_name='f',
3488
3750
Option('randomize', type=str, argname="SEED",
3489
3751
help='Randomize the order of tests using the given'
3490
3752
' seed or "now" for the current time.'),
3491
Option('exclude', type=str, argname="PATTERN",
3493
help='Exclude tests that match this regular'
3753
ListOption('exclude', type=str, argname="PATTERN",
3755
help='Exclude tests that match this regular'
3495
3757
Option('subunit',
3496
3758
help='Output test progress via subunit.'),
3497
3759
Option('strict', help='Fail on missing dependencies or '
3514
3776
def run(self, testspecs_list=None, verbose=False, one=False,
3515
3777
transport=None, benchmark=None,
3516
lsprof_timed=None, cache_dir=None,
3517
3779
first=False, list_only=False,
3518
3780
randomize=None, exclude=None, strict=False,
3519
3781
load_list=None, debugflag=None, starting_with=None, subunit=False,
3520
3782
parallel=None, lsprof_tests=False):
3521
from bzrlib.tests import selftest
3522
import bzrlib.benchmarks as benchmarks
3523
from bzrlib.benchmarks import tree_creator
3525
# Make deprecation warnings visible, unless -Werror is set
3526
symbol_versioning.activate_deprecation_warnings(override=False)
3528
if cache_dir is not None:
3529
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3783
from bzrlib import tests
3530
3785
if testspecs_list is not None:
3531
3786
pattern = '|'.join(testspecs_list)
3538
3793
raise errors.BzrCommandError("subunit not available. subunit "
3539
3794
"needs to be installed to use --subunit.")
3540
3795
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3796
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3797
# stdout, which would corrupt the subunit stream.
3798
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3799
# following code can be deleted when it's sufficiently deployed
3800
# -- vila/mgz 20100514
3801
if (sys.platform == "win32"
3802
and getattr(sys.stdout, 'fileno', None) is not None):
3804
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3542
3806
self.additional_selftest_args.setdefault(
3543
3807
'suite_decorators', []).append(parallel)
3545
test_suite_factory = benchmarks.test_suite
3546
# Unless user explicitly asks for quiet, be verbose in benchmarks
3547
verbose = not is_quiet()
3548
# TODO: should possibly lock the history file...
3549
benchfile = open(".perf_history", "at", buffering=1)
3550
self.add_cleanup(benchfile.close)
3809
raise errors.BzrCommandError(
3810
"--benchmark is no longer supported from bzr 2.2; "
3811
"use bzr-usertest instead")
3812
test_suite_factory = None
3814
exclude_pattern = None
3552
test_suite_factory = None
3816
exclude_pattern = '(' + '|'.join(exclude) + ')'
3554
3817
selftest_kwargs = {"verbose": verbose,
3555
3818
"pattern": pattern,
3556
3819
"stop_on_failure": one,
3558
3821
"test_suite_factory": test_suite_factory,
3559
3822
"lsprof_timed": lsprof_timed,
3560
3823
"lsprof_tests": lsprof_tests,
3561
"bench_history": benchfile,
3562
3824
"matching_tests_first": first,
3563
3825
"list_only": list_only,
3564
3826
"random_seed": randomize,
3565
"exclude_pattern": exclude,
3827
"exclude_pattern": exclude_pattern,
3566
3828
"strict": strict,
3567
3829
"load_list": load_list,
3568
3830
"debug_flags": debugflag,
3569
3831
"starting_with": starting_with
3571
3833
selftest_kwargs.update(self.additional_selftest_args)
3572
result = selftest(**selftest_kwargs)
3835
# Make deprecation warnings visible, unless -Werror is set
3836
cleanup = symbol_versioning.activate_deprecation_warnings(
3839
result = tests.selftest(**selftest_kwargs)
3573
3842
return int(not result)
3576
3845
class cmd_version(Command):
3577
"""Show version of bzr."""
3846
__doc__ = """Show version of bzr."""
3579
3848
encoding_type = 'replace'
3580
3849
takes_options = [
3614
3883
branch1 = Branch.open_containing(branch)[0]
3615
3884
branch2 = Branch.open_containing(other)[0]
3617
self.add_cleanup(branch1.unlock)
3619
self.add_cleanup(branch2.unlock)
3885
self.add_cleanup(branch1.lock_read().unlock)
3886
self.add_cleanup(branch2.lock_read().unlock)
3620
3887
last1 = ensure_null(branch1.last_revision())
3621
3888
last2 = ensure_null(branch2.last_revision())
3623
3890
graph = branch1.repository.get_graph(branch2.repository)
3624
3891
base_rev_id = graph.find_unique_lca(last1, last2)
3626
print 'merge base is revision %s' % base_rev_id
3893
self.outf.write('merge base is revision %s\n' % base_rev_id)
3629
3896
class cmd_merge(Command):
3630
"""Perform a three-way merge.
3897
__doc__ = """Perform a three-way merge.
3632
3899
The source of the merge can be specified either in the form of a branch,
3633
3900
or in the form of a path to a file containing a merge directive generated
3634
3901
with bzr send. If neither is specified, the default is the upstream branch
3635
or the branch most recently merged using --remember.
3637
When merging a branch, by default the tip will be merged. To pick a different
3638
revision, pass --revision. If you specify two values, the first will be used as
3639
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3640
available revisions, like this is commonly referred to as "cherrypicking".
3642
Revision numbers are always relative to the branch being merged.
3644
By default, bzr will try to merge in all new work from the other
3645
branch, automatically determining an appropriate base. If this
3646
fails, you may need to give an explicit base.
3902
or the branch most recently merged using --remember. The source of the
3903
merge may also be specified in the form of a path to a file in another
3904
branch: in this case, only the modifications to that file are merged into
3905
the current working tree.
3907
When merging from a branch, by default bzr will try to merge in all new
3908
work from the other branch, automatically determining an appropriate base
3909
revision. If this fails, you may need to give an explicit base.
3911
To pick a different ending revision, pass "--revision OTHER". bzr will
3912
try to merge in all new work up to and including revision OTHER.
3914
If you specify two values, "--revision BASE..OTHER", only revisions BASE
3915
through OTHER, excluding BASE but including OTHER, will be merged. If this
3916
causes some revisions to be skipped, i.e. if the destination branch does
3917
not already contain revision BASE, such a merge is commonly referred to as
3918
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
3919
cherrypicks. The changes look like a normal commit, and the history of the
3920
changes from the other branch is not stored in the commit.
3922
Revision numbers are always relative to the source branch.
3648
3924
Merge will do its best to combine the changes in two branches, but there
3649
3925
are some kinds of problems only a human can fix. When it encounters those,
3653
3929
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
3655
If there is no default branch set, the first merge will set it. After
3656
that, you can omit the branch to use the default. To change the
3657
default, use --remember. The value will only be saved if the remote
3658
location can be accessed.
3931
If there is no default branch set, the first merge will set it (use
3932
--no-remember to avoid settting it). After that, you can omit the branch
3933
to use the default. To change the default, use --remember. The value will
3934
only be saved if the remote location can be accessed.
3660
3936
The results of the merge are placed into the destination working
3661
3937
directory, where they can be reviewed (with bzr diff), tested, and then
3662
3938
committed to record the result of the merge.
3664
3940
merge refuses to run if there are any uncommitted changes, unless
3665
--force is given. The --force option can also be used to create a
3941
--force is given. If --force is given, then the changes from the source
3942
will be merged with the current working tree, including any uncommitted
3943
changes in the tree. The --force option can also be used to create a
3666
3944
merge revision which has more than two parents.
3668
3946
If one would like to merge changes from the working tree of the other
3716
3994
' completely merged into the source, pull from the'
3717
3995
' source rather than merging. When this happens,'
3718
3996
' you do not need to commit the result.'),
3997
custom_help('directory',
3720
3998
help='Branch to merge into, '
3721
'rather than the one containing the working directory.',
3999
'rather than the one containing the working directory.'),
3725
4000
Option('preview', help='Instead of merging, show a diff of the'
3727
4002
Option('interactive', help='Select changes interactively.',
3777
4055
raise errors.BzrCommandError(
3778
4056
'Cannot use -r with merge directives or bundles')
3779
4057
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3782
4060
if merger is None and uncommitted:
3783
4061
if revision is not None and len(revision) > 0:
3784
4062
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
4063
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
4064
merger = self.get_merger_from_uncommitted(tree, location, None)
3787
4065
allow_pending = False
3789
4067
if merger is None:
3790
4068
merger, allow_pending = self._get_merger_from_branch(tree,
3791
location, revision, remember, possible_transports, pb)
4069
location, revision, remember, possible_transports, None)
3793
4071
merger.merge_type = merge_type
3794
4072
merger.reprocess = reprocess
3796
4074
self.sanity_check_merger(merger)
3797
4075
if (merger.base_rev_id == merger.other_rev_id and
3798
4076
merger.other_rev_id is not None):
4077
# check if location is a nonexistent file (and not a branch) to
4078
# disambiguate the 'Nothing to do'
4079
if merger.interesting_files:
4080
if not merger.other_tree.has_filename(
4081
merger.interesting_files[0]):
4082
note("merger: " + str(merger))
4083
raise errors.PathsDoNotExist([location])
3799
4084
note('Nothing to do.')
4086
if pull and not preview:
3802
4087
if merger.interesting_files is not None:
3803
4088
raise errors.BzrCommandError('Cannot pull individual files')
3804
4089
if (merger.base_rev_id == tree.last_revision()):
3828
4113
def _do_preview(self, merger):
3829
4114
from bzrlib.diff import show_diff_trees
3830
4115
result_tree = self._get_preview(merger)
4116
path_encoding = osutils.get_diff_header_encoding()
3831
4117
show_diff_trees(merger.this_tree, result_tree, self.outf,
3832
old_label='', new_label='')
4118
old_label='', new_label='',
4119
path_encoding=path_encoding)
3834
4121
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3835
4122
merger.change_reporter = change_reporter
3911
4198
if other_revision_id is None:
3912
4199
other_revision_id = _mod_revision.ensure_null(
3913
4200
other_branch.last_revision())
3914
# Remember where we merge from
3915
if ((remember or tree.branch.get_submit_branch() is None) and
3916
user_location is not None):
4201
# Remember where we merge from. We need to remember if:
4202
# - user specify a location (and we don't merge from the parent
4204
# - user ask to remember or there is no previous location set to merge
4205
# from and user didn't ask to *not* remember
4206
if (user_location is not None
4208
or (remember is None
4209
and tree.branch.get_submit_branch() is None)))):
3917
4210
tree.branch.set_submit_branch(other_branch.base)
3918
_merge_tags_if_possible(other_branch, tree.branch)
4211
# Merge tags (but don't set them in the master branch yet, the user
4212
# might revert this merge). Commit will propagate them.
4213
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3919
4214
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3920
4215
other_revision_id, base_revision_id, other_branch, base_branch)
3921
4216
if other_path != '':
4020
4315
def run(self, file_list=None, merge_type=None, show_base=False,
4021
4316
reprocess=False):
4317
from bzrlib.conflicts import restore
4022
4318
if merge_type is None:
4023
4319
merge_type = _mod_merge.Merge3Merger
4024
tree, file_list = tree_files(file_list)
4026
self.add_cleanup(tree.unlock)
4320
tree, file_list = WorkingTree.open_containing_paths(file_list)
4321
self.add_cleanup(tree.lock_write().unlock)
4027
4322
parents = tree.get_parent_ids()
4028
4323
if len(parents) != 2:
4029
4324
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4065
4360
# list, we imply that the working tree text has seen and rejected
4066
4361
# all the changes from the other tree, when in fact those changes
4067
4362
# have not yet been seen.
4068
pb = ui.ui_factory.nested_progress_bar()
4069
4363
tree.set_parent_ids(parents[:1])
4071
merger = _mod_merge.Merger.from_revision_ids(pb,
4365
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4073
4366
merger.interesting_ids = interesting_ids
4074
4367
merger.merge_type = merge_type
4075
4368
merger.show_base = show_base
4087
4379
class cmd_revert(Command):
4088
"""Revert files to a previous revision.
4380
__doc__ = """Revert files to a previous revision.
4090
4382
Giving a list of files will revert only those files. Otherwise, all files
4091
4383
will be reverted. If the revision is not specified with '--revision', the
4092
4384
last committed revision is used.
4094
4386
To remove only some changes, without reverting to a prior version, use
4095
merge instead. For example, "merge . --revision -2..-3" will remove the
4096
changes introduced by -2, without affecting the changes introduced by -1.
4097
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4387
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4388
will remove the changes introduced by the second last commit (-2), without
4389
affecting the changes introduced by the last commit (-1). To remove
4390
certain changes on a hunk-by-hunk basis, see the shelve command.
4099
4392
By default, any files that have been manually changed will be backed up
4100
4393
first. (Files changed only by merge are not backed up.) Backup files have
4153
4445
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4154
4446
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4155
pb = ui.ui_factory.nested_progress_bar()
4157
tree.revert(file_list, rev_tree, not no_backup, pb,
4158
report_changes=True)
4447
tree.revert(file_list, rev_tree, not no_backup, None,
4448
report_changes=True)
4163
4451
class cmd_assert_fail(Command):
4164
"""Test reporting of assertion failures"""
4452
__doc__ = """Test reporting of assertion failures"""
4165
4453
# intended just for use in testing
4303
4595
remote_branch = Branch.open(other_branch)
4304
4596
if remote_branch.base == local_branch.base:
4305
4597
remote_branch = local_branch
4599
self.add_cleanup(remote_branch.lock_read().unlock)
4307
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4309
4601
local_revid_range = _revision_range_to_revid_range(
4310
4602
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4315
4605
remote_revid_range = _revision_range_to_revid_range(
4316
4606
_get_revision_range(revision,
4317
4607
remote_branch, self.name()))
4378
4667
class cmd_pack(Command):
4379
"""Compress the data within a repository."""
4668
__doc__ = """Compress the data within a repository.
4670
This operation compresses the data within a bazaar repository. As
4671
bazaar supports automatic packing of repository, this operation is
4672
normally not required to be done manually.
4674
During the pack operation, bazaar takes a backup of existing repository
4675
data, i.e. pack files. This backup is eventually removed by bazaar
4676
automatically when it is safe to do so. To save disk space by removing
4677
the backed up pack files, the --clean-obsolete-packs option may be
4680
Warning: If you use --clean-obsolete-packs and your machine crashes
4681
during or immediately after repacking, you may be left with a state
4682
where the deletion has been written to disk but the new packs have not
4683
been. In this case the repository may be unusable.
4381
4686
_see_also = ['repositories']
4382
4687
takes_args = ['branch_or_repo?']
4689
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4384
def run(self, branch_or_repo='.'):
4692
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4385
4693
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4387
4695
branch = dir.open_branch()
4388
4696
repository = branch.repository
4389
4697
except errors.NotBranchError:
4390
4698
repository = dir.open_repository()
4699
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4394
4702
class cmd_plugins(Command):
4395
"""List the installed plugins.
4703
__doc__ = """List the installed plugins.
4397
4705
This command displays the list of installed plugins including
4398
4706
version of plugin and a short description of each.
4415
4723
@display_command
4416
4724
def run(self, verbose=False):
4417
import bzrlib.plugin
4418
from inspect import getdoc
4420
for name, plugin in bzrlib.plugin.plugins().items():
4421
version = plugin.__version__
4422
if version == 'unknown':
4424
name_ver = '%s %s' % (name, version)
4425
d = getdoc(plugin.module)
4427
doc = d.split('\n')[0]
4429
doc = '(no description)'
4430
result.append((name_ver, doc, plugin.path()))
4431
for name_ver, doc, path in sorted(result):
4725
from bzrlib import plugin
4726
# Don't give writelines a generator as some codecs don't like that
4727
self.outf.writelines(
4728
list(plugin.describe_plugins(show_paths=verbose)))
4439
4731
class cmd_testament(Command):
4440
"""Show testament (signing-form) of a revision."""
4732
__doc__ = """Show testament (signing-form) of a revision."""
4441
4733
takes_options = [
4443
4735
Option('long', help='Produce long-format testament.'),
4486
4777
Option('long', help='Show commit date in annotations.'),
4490
4782
encoding_type = 'exact'
4492
4784
@display_command
4493
4785
def run(self, filename, all=False, long=False, revision=None,
4495
from bzrlib.annotate import annotate_file, annotate_file_tree
4786
show_ids=False, directory=None):
4787
from bzrlib.annotate import (
4496
4790
wt, branch, relpath = \
4497
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4791
_open_directory_or_containing_tree_or_branch(filename, directory)
4498
4792
if wt is not None:
4500
self.add_cleanup(wt.unlock)
4793
self.add_cleanup(wt.lock_read().unlock)
4503
self.add_cleanup(branch.unlock)
4795
self.add_cleanup(branch.lock_read().unlock)
4504
4796
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4506
self.add_cleanup(tree.unlock)
4797
self.add_cleanup(tree.lock_read().unlock)
4798
if wt is not None and revision is None:
4508
4799
file_id = wt.path2id(relpath)
4510
4801
file_id = tree.path2id(relpath)
4511
4802
if file_id is None:
4512
4803
raise errors.NotVersionedError(filename)
4513
file_version = tree.inventory[file_id].revision
4514
4804
if wt is not None and revision is None:
4515
4805
# If there is a tree and we're not annotating historical
4516
4806
# versions, annotate the working tree's content.
4517
4807
annotate_file_tree(wt, file_id, self.outf, long, all,
4518
4808
show_ids=show_ids)
4520
annotate_file(branch, file_version, file_id, long, all, self.outf,
4810
annotate_file_tree(tree, file_id, self.outf, long, all,
4811
show_ids=show_ids, branch=branch)
4524
4814
class cmd_re_sign(Command):
4525
"""Create a digital signature for an existing revision."""
4815
__doc__ = """Create a digital signature for an existing revision."""
4526
4816
# TODO be able to replace existing ones.
4528
4818
hidden = True # is this right ?
4529
4819
takes_args = ['revision_id*']
4530
takes_options = ['revision']
4820
takes_options = ['directory', 'revision']
4532
def run(self, revision_id_list=None, revision=None):
4822
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4533
4823
if revision_id_list is not None and revision is not None:
4534
4824
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4535
4825
if revision_id_list is None and revision is None:
4536
4826
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4537
b = WorkingTree.open_containing(u'.')[0].branch
4539
self.add_cleanup(b.unlock)
4827
b = WorkingTree.open_containing(directory)[0].branch
4828
self.add_cleanup(b.lock_write().unlock)
4540
4829
return self._run(b, revision_id_list, revision)
4542
4831
def _run(self, b, revision_id_list, revision):
4637
4927
_see_also = ['checkouts', 'bind']
4638
4928
takes_args = []
4929
takes_options = ['directory']
4642
b, relpath = Branch.open_containing(u'.')
4931
def run(self, directory=u'.'):
4932
b, relpath = Branch.open_containing(directory)
4643
4933
if not b.unbind():
4644
4934
raise errors.BzrCommandError('Local branch is not bound')
4647
4937
class cmd_uncommit(Command):
4648
"""Remove the last committed revision.
4938
__doc__ = """Remove the last committed revision.
4650
4940
--verbose will print out what is being removed.
4651
4941
--dry-run will go through all the motions, but not actually
4691
4981
b = control.open_branch()
4693
4983
if tree is not None:
4695
self.add_cleanup(tree.unlock)
4984
self.add_cleanup(tree.lock_write().unlock)
4698
self.add_cleanup(b.unlock)
4986
self.add_cleanup(b.lock_write().unlock)
4699
4987
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4701
4989
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
4735
5022
end_revision=last_revno)
4738
ui.ui_factory.note('Dry-run, pretending to remove the above revisions.')
5025
self.outf.write('Dry-run, pretending to remove'
5026
' the above revisions.\n')
4740
ui.ui_factory.note('The above revision(s) will be removed.')
5028
self.outf.write('The above revision(s) will be removed.\n')
4743
if not ui.ui_factory.get_boolean('Are you sure [y/N]? '):
4744
ui.ui_factory.note('Canceled')
5031
if not ui.ui_factory.confirm_action(
5032
u'Uncommit these revisions',
5033
'bzrlib.builtins.uncommit',
5035
self.outf.write('Canceled\n')
4747
5038
mutter('Uncommitting from {%s} to {%s}',
4748
5039
last_rev_id, rev_id)
4749
5040
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4750
5041
revno=revno, local=local)
4751
ui.ui_factory.note('You can restore the old tip by running:\n'
4752
' bzr pull . -r revid:%s' % last_rev_id)
5042
self.outf.write('You can restore the old tip by running:\n'
5043
' bzr pull . -r revid:%s\n' % last_rev_id)
4755
5046
class cmd_break_lock(Command):
4756
"""Break a dead lock on a repository, branch or working directory.
5047
__doc__ = """Break a dead lock.
5049
This command breaks a lock on a repository, branch, working directory or
4758
5052
CAUTION: Locks should only be broken when you are sure that the process
4759
5053
holding the lock has been stopped.
4766
5060
bzr break-lock bzr+ssh://example.com/bzr/foo
5061
bzr break-lock --conf ~/.bazaar
4768
5064
takes_args = ['location?']
5067
help='LOCATION is the directory where the config lock is.'),
5069
help='Do not ask for confirmation before breaking the lock.'),
4770
def run(self, location=None, show=False):
5072
def run(self, location=None, config=False, force=False):
4771
5073
if location is None:
4772
5074
location = u'.'
4773
control, relpath = bzrdir.BzrDir.open_containing(location)
4775
control.break_lock()
4776
except NotImplementedError:
5076
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5078
{'bzrlib.lockdir.break': True})
5080
conf = _mod_config.LockableConfig(file_name=location)
5083
control, relpath = bzrdir.BzrDir.open_containing(location)
5085
control.break_lock()
5086
except NotImplementedError:
4780
5090
class cmd_wait_until_signalled(Command):
4781
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5091
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4783
5093
This just prints a line to signal when it is ready, then blocks on stdin.
4845
5154
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4846
5155
protocol=None):
4847
from bzrlib.transport import get_transport, transport_server_registry
5156
from bzrlib import transport
4848
5157
if directory is None:
4849
5158
directory = os.getcwd()
4850
5159
if protocol is None:
4851
protocol = transport_server_registry.get()
5160
protocol = transport.transport_server_registry.get()
4852
5161
host, port = self.get_host_and_port(port)
4853
5162
url = urlutils.local_path_to_url(directory)
4854
5163
if not allow_writes:
4855
5164
url = 'readonly+' + url
4856
transport = get_transport(url)
4857
protocol(transport, host, port, inet)
5165
t = transport.get_transport(url)
5166
protocol(t, host, port, inet)
4860
5169
class cmd_join(Command):
4861
"""Combine a tree into its containing tree.
5170
__doc__ = """Combine a tree into its containing tree.
4863
5172
This command requires the target tree to be in a rich-root format.
4971
5281
encoding_type = 'exact'
4973
5283
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
4974
sign=False, revision=None, mail_to=None, message=None):
5284
sign=False, revision=None, mail_to=None, message=None,
4975
5286
from bzrlib.revision import ensure_null, NULL_REVISION
4976
5287
include_patch, include_bundle = {
4977
5288
'plain': (False, False),
4978
5289
'diff': (True, False),
4979
5290
'bundle': (True, True),
4981
branch = Branch.open('.')
5292
branch = Branch.open(directory)
4982
5293
stored_submit_branch = branch.get_submit_branch()
4983
5294
if submit_branch is None:
4984
5295
submit_branch = stored_submit_branch
5060
5371
source branch defaults to that containing the working directory, but can
5061
5372
be changed using --from.
5374
Both the submit branch and the public branch follow the usual behavior with
5375
respect to --remember: If there is no default location set, the first send
5376
will set it (use --no-remember to avoid settting it). After that, you can
5377
omit the location to use the default. To change the default, use
5378
--remember. The value will only be saved if the location can be accessed.
5063
5380
In order to calculate those changes, bzr must analyse the submit branch.
5064
5381
Therefore it is most efficient for the submit branch to be a local mirror.
5065
5382
If a public location is known for the submit_branch, that location is used
5234
5551
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5235
5552
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5554
If no tag name is specified it will be determined through the
5555
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5556
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5238
5560
_see_also = ['commit', 'tags']
5239
takes_args = ['tag_name']
5561
takes_args = ['tag_name?']
5240
5562
takes_options = [
5241
5563
Option('delete',
5242
5564
help='Delete this tag rather than placing it.',
5245
help='Branch in which to place the tag.',
5566
custom_help('directory',
5567
help='Branch in which to place the tag.'),
5249
5568
Option('force',
5250
5569
help='Replace existing tags.',
5255
def run(self, tag_name,
5574
def run(self, tag_name=None,
5261
5580
branch, relpath = Branch.open_containing(directory)
5263
self.add_cleanup(branch.unlock)
5581
self.add_cleanup(branch.lock_write().unlock)
5583
if tag_name is None:
5584
raise errors.BzrCommandError("No tag specified to delete.")
5265
5585
branch.tags.delete_tag(tag_name)
5266
self.outf.write('Deleted tag %s.\n' % tag_name)
5586
note('Deleted tag %s.' % tag_name)
5269
5589
if len(revision) != 1:
5273
5593
revision_id = revision[0].as_revision_id(branch)
5275
5595
revision_id = branch.last_revision()
5596
if tag_name is None:
5597
tag_name = branch.automatic_tag_name(revision_id)
5598
if tag_name is None:
5599
raise errors.BzrCommandError(
5600
"Please specify a tag name.")
5276
5601
if (not force) and branch.tags.has_tag(tag_name):
5277
5602
raise errors.TagAlreadyExists(tag_name)
5278
5603
branch.tags.set_tag(tag_name, revision_id)
5279
self.outf.write('Created tag %s.\n' % tag_name)
5604
note('Created tag %s.' % tag_name)
5282
5607
class cmd_tags(Command):
5608
__doc__ = """List tags.
5285
5610
This command shows a table of tag names and the revisions they reference.
5288
5613
_see_also = ['tag']
5289
5614
takes_options = [
5291
help='Branch whose tags should be displayed.',
5295
RegistryOption.from_kwargs('sort',
5615
custom_help('directory',
5616
help='Branch whose tags should be displayed.'),
5617
RegistryOption('sort',
5296
5618
'Sort tags by different criteria.', title='Sorting',
5297
alpha='Sort tags lexicographically (default).',
5298
time='Sort tags chronologically.',
5619
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5304
5625
@display_command
5626
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5627
from bzrlib.tag import tag_sort_methods
5311
5628
branch, relpath = Branch.open_containing(directory)
5313
5630
tags = branch.tags.get_tag_dict().items()
5318
self.add_cleanup(branch.unlock)
5634
self.add_cleanup(branch.lock_read().unlock)
5320
5636
graph = branch.repository.get_graph()
5321
5637
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5323
5639
# only show revisions between revid1 and revid2 (inclusive)
5324
5640
tags = [(tag, revid) for tag, revid in tags if
5325
5641
graph.is_between(revid, revid1, revid2)]
5328
elif sort == 'time':
5330
for tag, revid in tags:
5332
revobj = branch.repository.get_revision(revid)
5333
except errors.NoSuchRevision:
5334
timestamp = sys.maxint # place them at the end
5336
timestamp = revobj.timestamp
5337
timestamps[revid] = timestamp
5338
tags.sort(key=lambda x: timestamps[x[1]])
5643
sort = tag_sort_methods.get()
5339
5645
if not show_ids:
5340
5646
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5341
5647
for index, (tag, revid) in enumerate(tags):
5479
5786
def run(self, to_location=None, force=False, create_branch=False,
5787
revision=None, directory=u'.'):
5481
5788
from bzrlib import switch
5789
tree_location = directory
5483
5790
revision = _get_one_revision('switch', revision)
5484
5791
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5485
5792
if to_location is None:
5486
5793
if revision is None:
5487
5794
raise errors.BzrCommandError('You must supply either a'
5488
5795
' revision or a location')
5796
to_location = tree_location
5491
5798
branch = control_dir.open_branch()
5492
5799
had_explicit_nick = branch.get_config().has_explicit_nickname()
5714
6022
self.outf.write(" <no hooks installed>\n")
6025
class cmd_remove_branch(Command):
6026
__doc__ = """Remove a branch.
6028
This will remove the branch from the specified location but
6029
will keep any working tree or repository in place.
6033
Remove the branch at repo/trunk::
6035
bzr remove-branch repo/trunk
6039
takes_args = ["location?"]
6041
aliases = ["rmbranch"]
6043
def run(self, location=None):
6044
if location is None:
6046
branch = Branch.open_containing(location)[0]
6047
branch.bzrdir.destroy_branch()
5717
6050
class cmd_shelve(Command):
5718
"""Temporarily set aside some changes from the current tree.
6051
__doc__ = """Temporarily set aside some changes from the current tree.
5720
6053
Shelve allows you to temporarily put changes you've made "on the shelf",
5721
6054
ie. out of the way, until a later time when you can bring them back from
5738
6071
You can put multiple items on the shelf, and by default, 'unshelve' will
5739
6072
restore the most recently shelved changes.
6074
For complicated changes, it is possible to edit the changes in a separate
6075
editor program to decide what the file remaining in the working copy
6076
should look like. To do this, add the configuration option
6078
change_editor = PROGRAM @new_path @old_path
6080
where @new_path is replaced with the path of the new version of the
6081
file and @old_path is replaced with the path of the old version of
6082
the file. The PROGRAM should save the new file with the desired
6083
contents of the file in the working tree.
5742
6087
takes_args = ['file*']
5744
6089
takes_options = [
5746
6092
Option('all', help='Shelve all changes.'),
5753
6099
Option('destroy',
5754
6100
help='Destroy removed changes instead of shelving them.'),
5756
_see_also = ['unshelve']
6102
_see_also = ['unshelve', 'configuration']
5758
6104
def run(self, revision=None, all=False, file_list=None, message=None,
5759
writer=None, list=False, destroy=False):
6105
writer=None, list=False, destroy=False, directory=None):
5761
return self.run_for_list()
6107
return self.run_for_list(directory=directory)
5762
6108
from bzrlib.shelf_ui import Shelver
5763
6109
if writer is None:
5764
6110
writer = bzrlib.option.diff_writer_registry.get()
5766
6112
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5767
file_list, message, destroy=destroy)
6113
file_list, message, destroy=destroy, directory=directory)
5837
6185
To check what clean-tree will do, use --dry-run.
5839
takes_options = [Option('ignored', help='Delete all ignored files.'),
5840
Option('detritus', help='Delete conflict files, merge'
6187
takes_options = ['directory',
6188
Option('ignored', help='Delete all ignored files.'),
6189
Option('detritus', help='Delete conflict files, merge and revert'
5841
6190
' backups, and failed selftest dirs.'),
5842
6191
Option('unknown',
5843
6192
help='Delete files unknown to bzr (default).'),
5845
6194
' deleting them.'),
5846
6195
Option('force', help='Do not prompt before deleting.')]
5847
6196
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6197
force=False, directory=u'.'):
5849
6198
from bzrlib.clean_tree import clean_tree
5850
6199
if not (unknown or ignored or detritus):
5854
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5855
dry_run=dry_run, no_prompt=force)
6203
clean_tree(directory, unknown=unknown, ignored=ignored,
6204
detritus=detritus, dry_run=dry_run, no_prompt=force)
5858
6207
class cmd_reference(Command):
5859
"""list, view and set branch locations for nested trees.
6208
__doc__ = """list, view and set branch locations for nested trees.
5861
6210
If no arguments are provided, lists the branch locations for nested trees.
5862
6211
If one argument is provided, display the branch location for that tree.
5902
6251
self.outf.write('%s %s\n' % (path, location))
5905
# these get imported and then picked up by the scan for cmd_*
5906
# TODO: Some more consistent way to split command definitions across files;
5907
# we do need to load at least some information about them to know of
5908
# aliases. ideally we would avoid loading the implementation until the
5909
# details were needed.
5910
from bzrlib.cmd_version_info import cmd_version_info
5911
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5912
from bzrlib.bundle.commands import (
5915
from bzrlib.foreign import cmd_dpush
5916
from bzrlib.sign_my_commits import cmd_sign_my_commits
5917
from bzrlib.weave_commands import cmd_versionedfile_list, \
5918
cmd_weave_plan_merge, cmd_weave_merge_text
6254
class cmd_export_pot(Command):
6255
__doc__ = """Export command helps and error messages in po format."""
6260
from bzrlib.export_pot import export_pot
6261
export_pot(self.outf)
6264
def _register_lazy_builtins():
6265
# register lazy builtins from other modules; called at startup and should
6266
# be only called once.
6267
for (name, aliases, module_name) in [
6268
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6269
('cmd_config', [], 'bzrlib.config'),
6270
('cmd_dpush', [], 'bzrlib.foreign'),
6271
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6272
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6273
('cmd_conflicts', [], 'bzrlib.conflicts'),
6274
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6275
('cmd_verify_signatures', [],
6276
'bzrlib.commit_signature_commands'),
6277
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6279
builtin_command_registry.register_lazy(name, aliases, module_name)