175
167
:return: workingtree, [relative_paths]
177
return WorkingTree.open_containing_paths(
178
file_list, default_directory='.',
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)
183
218
def _get_view_info_for_change_reporter(tree):
320
337
takes_args = ['revision_id?']
321
takes_options = ['directory', 'revision']
338
takes_options = ['revision']
322
339
# cat-revision is more for frontends so should be exact
323
340
encoding = 'strict'
325
def print_revision(self, revisions, revid):
326
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
327
record = stream.next()
328
if record.storage_kind == 'absent':
329
raise errors.NoSuchRevision(revisions, revid)
330
revtext = record.get_bytes_as('fulltext')
331
self.outf.write(revtext.decode('utf-8'))
334
def run(self, revision_id=None, revision=None, directory=u'.'):
343
def run(self, revision_id=None, revision=None):
335
344
if revision_id is not None and revision is not None:
336
raise errors.BzrCommandError(gettext('You can only supply one of'
337
' revision_id or --revision'))
345
raise errors.BzrCommandError('You can only supply one of'
346
' revision_id or --revision')
338
347
if revision_id is None and revision is None:
339
raise errors.BzrCommandError(gettext('You must supply either'
340
' --revision or a revision_id'))
342
b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
344
revisions = b.repository.revisions
345
if revisions is None:
346
raise errors.BzrCommandError(gettext('Repository %r does not support '
347
'access to raw revision texts'))
349
b.repository.lock_read()
351
# TODO: jam 20060112 should cat-revision always output utf-8?
352
if revision_id is not None:
353
revision_id = osutils.safe_revision_id(revision_id, warn=False)
355
self.print_revision(revisions, revision_id)
356
except errors.NoSuchRevision:
357
msg = gettext("The repository {0} contains no revision {1}.").format(
358
b.repository.base, revision_id)
359
raise errors.BzrCommandError(msg)
360
elif revision is not None:
363
raise errors.BzrCommandError(
364
gettext('You cannot specify a NULL revision.'))
365
rev_id = rev.as_revision_id(b)
366
self.print_revision(revisions, rev_id)
368
b.repository.unlock()
348
raise errors.BzrCommandError('You must supply either'
349
' --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'))
371
370
class cmd_dump_btree(Command):
372
__doc__ = """Dump the contents of a btree index file to stdout.
371
"""Dump the contents of a btree index file to stdout.
374
373
PATH is a btree index file, it can be any URL. This includes things like
375
374
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
461
452
To re-create the working tree, use "bzr checkout".
463
454
_see_also = ['checkout', 'working-trees']
464
takes_args = ['location*']
455
takes_args = ['location?']
465
456
takes_options = [
467
458
help='Remove the working tree even if it has '
468
'uncommitted or shelved changes.'),
459
'uncommitted changes.'),
471
def run(self, location_list, force=False):
472
if not location_list:
475
for location in location_list:
476
d = bzrdir.BzrDir.open(location)
479
working = d.open_workingtree()
480
except errors.NoWorkingTree:
481
raise errors.BzrCommandError(gettext("No working tree to remove"))
482
except errors.NotLocalUrl:
483
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
484
" of a remote path"))
486
if (working.has_changes()):
487
raise errors.UncommittedChanges(working)
488
if working.get_shelf_manager().last_shelf() is not None:
489
raise errors.ShelvedChanges(working)
491
if working.user_url != working.branch.user_url:
492
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
493
" from a lightweight checkout"))
495
d.destroy_workingtree()
498
class cmd_repair_workingtree(Command):
499
__doc__ = """Reset the working tree state file.
501
This is not meant to be used normally, but more as a way to recover from
502
filesystem corruption, etc. This rebuilds the working inventory back to a
503
'known good' state. Any new modifications (adding a file, renaming, etc)
504
will be lost, though modified files will still be detected as such.
506
Most users will want something more like "bzr revert" or "bzr update"
507
unless the state file has become corrupted.
509
By default this attempts to recover the current state by looking at the
510
headers of the state file. If the state file is too corrupted to even do
511
that, you can supply --revision to force the state of the tree.
514
takes_options = ['revision', 'directory',
516
help='Reset the tree even if it doesn\'t appear to be'
521
def run(self, revision=None, directory='.', force=False):
522
tree, _ = WorkingTree.open_containing(directory)
523
self.add_cleanup(tree.lock_tree_write().unlock)
462
def run(self, location='.', force=False):
463
d = bzrdir.BzrDir.open(location)
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"
527
except errors.BzrError:
528
pass # There seems to be a real error here, so we'll reset
531
raise errors.BzrCommandError(gettext(
532
'The tree does not appear to be corrupt. You probably'
533
' want "bzr revert" instead. Use "--force" if you are'
534
' sure you want to reset the working tree.'))
538
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
540
tree.reset_state(revision_ids)
541
except errors.BzrError, e:
542
if revision_ids is None:
543
extra = (gettext(', the header appears corrupt, try passing -r -1'
544
' to set the state to the last commit'))
547
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
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()
550
485
class cmd_revno(Command):
551
__doc__ = """Show current revision number.
486
"""Show current revision number.
553
488
This is equal to the number of revisions on this branch.
602
546
wt = WorkingTree.open_containing(directory)[0]
604
self.add_cleanup(wt.lock_read().unlock)
605
549
except (errors.NoWorkingTree, errors.NotLocalUrl):
607
551
b = Branch.open_containing(directory)[0]
608
self.add_cleanup(b.lock_read().unlock)
610
if revision is not None:
611
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
612
if revision_info_list is not None:
613
for rev_str in revision_info_list:
614
rev_spec = RevisionSpec.from_string(rev_str)
615
revision_ids.append(rev_spec.as_revision_id(b))
616
# No arguments supplied, default to the last revision
617
if len(revision_ids) == 0:
620
raise errors.NoWorkingTree(directory)
621
revision_ids.append(wt.last_revision())
555
if revision is not None:
556
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
557
if revision_info_list is not None:
558
for rev_str in revision_info_list:
559
rev_spec = RevisionSpec.from_string(rev_str)
560
revision_ids.append(rev_spec.as_revision_id(b))
561
# No arguments supplied, default to the last revision
562
if len(revision_ids) == 0:
565
raise errors.NoWorkingTree(directory)
566
revision_ids.append(wt.last_revision())
568
revision_ids.append(b.last_revision())
572
for revision_id in revision_ids:
574
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
575
revno = '.'.join(str(i) for i in dotted_revno)
576
except errors.NoSuchRevision:
578
maxlen = max(maxlen, len(revno))
579
revinfos.append([revno, revision_id])
623
revision_ids.append(b.last_revision())
627
for revision_id in revision_ids:
629
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
630
revno = '.'.join(str(i) for i in dotted_revno)
631
except errors.NoSuchRevision:
633
maxlen = max(maxlen, len(revno))
634
revinfos.append([revno, revision_id])
637
586
for ri in revinfos:
638
587
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
641
590
class cmd_add(Command):
642
__doc__ = """Add specified files or directories.
591
"""Add specified files or directories.
644
593
In non-recursive mode, all the named items are added, regardless
645
594
of whether they were previously ignored. A warning is given if
793
732
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
794
733
if kind and kind not in ['file', 'directory', 'symlink']:
795
raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
734
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
797
736
revision = _get_one_revision('inventory', revision)
798
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
799
self.add_cleanup(work_tree.lock_read().unlock)
800
if revision is not None:
801
tree = revision.as_tree(work_tree.branch)
803
extra_trees = [work_tree]
804
self.add_cleanup(tree.lock_read().unlock)
809
if file_list is not None:
810
file_ids = tree.paths2ids(file_list, trees=extra_trees,
811
require_versioned=True)
812
# find_ids_across_trees may include some paths that don't
815
(tree.id2path(file_id), tree.inventory[file_id])
816
for file_id in file_ids if tree.has_id(file_id))
818
entries = tree.inventory.entries()
737
work_tree, file_list = tree_files(file_list)
738
work_tree.lock_read()
740
if revision is not None:
741
tree = revision.as_tree(work_tree.branch)
743
extra_trees = [work_tree]
749
if file_list is not None:
750
file_ids = tree.paths2ids(file_list, trees=extra_trees,
751
require_versioned=True)
752
# find_ids_across_trees may include some paths that don't
754
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
755
for file_id in file_ids if file_id in tree)
757
entries = tree.inventory.entries()
760
if tree is not work_tree:
821
763
for path, entry in entries:
822
764
if kind and kind != entry.kind:
863
805
return self.run_auto(names_list, after, dry_run)
865
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
807
raise errors.BzrCommandError('--dry-run requires --auto.')
866
808
if names_list is None:
868
810
if len(names_list) < 2:
869
raise errors.BzrCommandError(gettext("missing file argument"))
870
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
871
self.add_cleanup(tree.lock_tree_write().unlock)
872
self._run(tree, names_list, rel_names, after)
811
raise errors.BzrCommandError("missing file argument")
812
tree, rel_names = tree_files(names_list, canonicalize=False)
813
tree.lock_tree_write()
815
self._run(tree, names_list, rel_names, after)
874
819
def run_auto(self, names_list, after, dry_run):
875
820
if names_list is not None and len(names_list) > 1:
876
raise errors.BzrCommandError(gettext('Only one path may be specified to'
821
raise errors.BzrCommandError('Only one path may be specified to'
879
raise errors.BzrCommandError(gettext('--after cannot be specified with'
881
work_tree, file_list = WorkingTree.open_containing_paths(
882
names_list, default_directory='.')
883
self.add_cleanup(work_tree.lock_tree_write().unlock)
884
rename_map.RenameMap.guess_renames(work_tree, dry_run)
824
raise errors.BzrCommandError('--after cannot be specified with'
826
work_tree, file_list = tree_files(names_list, default_branch='.')
827
work_tree.lock_tree_write()
829
rename_map.RenameMap.guess_renames(work_tree, dry_run)
886
833
def _run(self, tree, names_list, rel_names, after):
887
834
into_existing = osutils.isdir(names_list[-1])
1065
1007
branch_from = Branch.open(location,
1066
1008
possible_transports=possible_transports)
1067
self.add_cleanup(branch_from.lock_read().unlock)
1068
# Remembers if asked explicitly or no previous location is set
1070
or (remember is None and branch_to.get_parent() is None)):
1010
if branch_to.get_parent() is None or remember:
1071
1011
branch_to.set_parent(branch_from.base)
1073
if revision is not None:
1074
revision_id = revision.as_revision_id(branch_from)
1076
if tree_to is not None:
1077
view_info = _get_view_info_for_change_reporter(tree_to)
1078
change_reporter = delta._ChangeReporter(
1079
unversioned_filter=tree_to.is_ignored,
1080
view_info=view_info)
1081
result = tree_to.pull(
1082
branch_from, overwrite, revision_id, change_reporter,
1083
local=local, show_base=show_base)
1085
result = branch_to.pull(
1086
branch_from, overwrite, revision_id, local=local)
1088
result.report(self.outf)
1089
if verbose and result.old_revid != result.new_revid:
1090
log.show_branch_change(
1091
branch_to, self.outf, result.old_revno,
1093
if getattr(result, 'tag_conflicts', None):
1013
if branch_from is not branch_to:
1014
branch_from.lock_read()
1016
if revision is not None:
1017
revision_id = revision.as_revision_id(branch_from)
1019
branch_to.lock_write()
1021
if tree_to is not None:
1022
view_info = _get_view_info_for_change_reporter(tree_to)
1023
change_reporter = delta._ChangeReporter(
1024
unversioned_filter=tree_to.is_ignored,
1025
view_info=view_info)
1026
result = tree_to.pull(
1027
branch_from, overwrite, revision_id, change_reporter,
1028
possible_transports=possible_transports, local=local)
1030
result = branch_to.pull(
1031
branch_from, overwrite, revision_id, local=local)
1033
result.report(self.outf)
1034
if verbose and result.old_revid != result.new_revid:
1035
log.show_branch_change(
1036
branch_to, self.outf, result.old_revno,
1041
if branch_from is not branch_to:
1042
branch_from.unlock()
1099
1045
class cmd_push(Command):
1100
__doc__ = """Update a mirror of this branch.
1046
"""Update a mirror of this branch.
1102
1048
The target branch will not have its working tree populated because this
1103
1049
is both expensive, and is not supported on remote file systems.
1190
1145
# error by the feedback given to them. RBC 20080227.
1191
1146
stacked_on = parent_url
1192
1147
if not stacked_on:
1193
raise errors.BzrCommandError(gettext(
1194
"Could not determine branch to refer to."))
1148
raise errors.BzrCommandError(
1149
"Could not determine branch to refer to.")
1196
1151
# Get the destination location
1197
1152
if location is None:
1198
1153
stored_loc = br_from.get_push_location()
1199
1154
if stored_loc is None:
1200
raise errors.BzrCommandError(gettext(
1201
"No push location known or specified."))
1155
raise errors.BzrCommandError(
1156
"No push location known or specified.")
1203
1158
display_url = urlutils.unescape_for_display(stored_loc,
1204
1159
self.outf.encoding)
1205
note(gettext("Using saved push location: %s") % display_url)
1160
self.outf.write("Using saved push location: %s\n" % display_url)
1206
1161
location = stored_loc
1208
1163
_show_push_branch(br_from, revision_id, location, self.outf,
1209
1164
verbose=verbose, overwrite=overwrite, remember=remember,
1210
1165
stacked_on=stacked_on, create_prefix=create_prefix,
1211
use_existing_dir=use_existing_dir, no_tree=no_tree)
1166
use_existing_dir=use_existing_dir)
1214
1169
class cmd_branch(Command):
1215
__doc__ = """Create a new branch that is a copy of an existing branch.
1170
"""Create a new branch that is a copy of an existing branch.
1217
1172
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1218
1173
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1249
1200
' directory exists, but does not already'
1250
1201
' have a control directory. This flag will'
1251
1202
' allow branch to proceed.'),
1253
help="Bind new branch to from location."),
1255
1204
aliases = ['get', 'clone']
1257
1206
def run(self, from_location, to_location=None, revision=None,
1258
1207
hardlink=False, stacked=False, standalone=False, no_tree=False,
1259
use_existing_dir=False, switch=False, bind=False,
1208
use_existing_dir=False, switch=False):
1261
1209
from bzrlib import switch as _mod_switch
1262
1210
from bzrlib.tag import _merge_tags_if_possible
1263
if self.invoked_as in ['get', 'clone']:
1264
ui.ui_factory.show_user_warning(
1265
'deprecated_command',
1266
deprecated_name=self.invoked_as,
1267
recommended_name='branch',
1268
deprecated_in_version='2.4')
1269
1211
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1271
if not (hardlink or files_from):
1272
# accelerator_tree is usually slower because you have to read N
1273
# files (no readahead, lots of seeks, etc), but allow the user to
1274
# explicitly request it
1275
accelerator_tree = None
1276
if files_from is not None and files_from != from_location:
1277
accelerator_tree = WorkingTree.open(files_from)
1278
1213
revision = _get_one_revision('branch', revision)
1279
self.add_cleanup(br_from.lock_read().unlock)
1280
if revision is not None:
1281
revision_id = revision.as_revision_id(br_from)
1283
# FIXME - wt.last_revision, fallback to branch, fall back to
1284
# None or perhaps NULL_REVISION to mean copy nothing
1286
revision_id = br_from.last_revision()
1287
if to_location is None:
1288
to_location = urlutils.derive_to_location(from_location)
1289
to_transport = transport.get_transport(to_location)
1291
to_transport.mkdir('.')
1292
except errors.FileExists:
1293
if not use_existing_dir:
1294
raise errors.BzrCommandError(gettext('Target directory "%s" '
1295
'already exists.') % to_location)
1216
if revision is not None:
1217
revision_id = revision.as_revision_id(br_from)
1298
bzrdir.BzrDir.open_from_transport(to_transport)
1299
except errors.NotBranchError:
1302
raise errors.AlreadyBranchError(to_location)
1303
except errors.NoSuchFile:
1304
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1307
# preserve whatever source format we have.
1308
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1309
possible_transports=[to_transport],
1310
accelerator_tree=accelerator_tree,
1311
hardlink=hardlink, stacked=stacked,
1312
force_new_repo=standalone,
1313
create_tree_if_local=not no_tree,
1314
source_branch=br_from)
1315
branch = dir.open_branch()
1316
except errors.NoSuchRevision:
1317
to_transport.delete_tree('.')
1318
msg = gettext("The branch {0} has no revision {1}.").format(
1319
from_location, revision)
1320
raise errors.BzrCommandError(msg)
1321
_merge_tags_if_possible(br_from, branch)
1322
# If the source branch is stacked, the new branch may
1323
# be stacked whether we asked for that explicitly or not.
1324
# We therefore need a try/except here and not just 'if stacked:'
1326
note(gettext('Created new stacked branch referring to %s.') %
1327
branch.get_stacked_on_url())
1328
except (errors.NotStacked, errors.UnstackableBranchFormat,
1329
errors.UnstackableRepositoryFormat), e:
1330
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1332
# Bind to the parent
1333
parent_branch = Branch.open(from_location)
1334
branch.bind(parent_branch)
1335
note(gettext('New branch bound to %s') % from_location)
1337
# Switch to the new branch
1338
wt, _ = WorkingTree.open_containing('.')
1339
_mod_switch.switch(wt.bzrdir, branch)
1340
note(gettext('Switched to branch: %s'),
1341
urlutils.unescape_for_display(branch.base, 'utf-8'))
1344
class cmd_branches(Command):
1345
__doc__ = """List the branches available at the current location.
1347
This command will print the names of all the branches at the current
1351
takes_args = ['location?']
1353
Option('recursive', short_name='R',
1354
help='Recursively scan for branches rather than '
1355
'just looking in the specified location.')]
1357
def run(self, location=".", recursive=False):
1359
t = transport.get_transport(location)
1360
if not t.listable():
1361
raise errors.BzrCommandError(
1362
"Can't scan this type of location.")
1363
for b in bzrdir.BzrDir.find_branches(t):
1364
self.outf.write("%s\n" % urlutils.unescape_for_display(
1365
urlutils.relative_url(t.base, b.base),
1366
self.outf.encoding).rstrip("/"))
1368
dir = bzrdir.BzrDir.open_containing(location)[0]
1369
for branch in dir.list_branches():
1370
if branch.name is None:
1371
self.outf.write(gettext(" (default)\n"))
1373
self.outf.write(" %s\n" % branch.name.encode(
1374
self.outf.encoding))
1219
# FIXME - wt.last_revision, fallback to branch, fall back to
1220
# None or perhaps NULL_REVISION to mean copy nothing
1222
revision_id = br_from.last_revision()
1223
if to_location is None:
1224
to_location = urlutils.derive_to_location(from_location)
1225
to_transport = transport.get_transport(to_location)
1227
to_transport.mkdir('.')
1228
except errors.FileExists:
1229
if not use_existing_dir:
1230
raise errors.BzrCommandError('Target directory "%s" '
1231
'already exists.' % to_location)
1234
bzrdir.BzrDir.open_from_transport(to_transport)
1235
except errors.NotBranchError:
1238
raise errors.AlreadyBranchError(to_location)
1239
except errors.NoSuchFile:
1240
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1243
# preserve whatever source format we have.
1244
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1245
possible_transports=[to_transport],
1246
accelerator_tree=accelerator_tree,
1247
hardlink=hardlink, stacked=stacked,
1248
force_new_repo=standalone,
1249
create_tree_if_local=not no_tree,
1250
source_branch=br_from)
1251
branch = dir.open_branch()
1252
except errors.NoSuchRevision:
1253
to_transport.delete_tree('.')
1254
msg = "The branch %s has no revision %s." % (from_location,
1256
raise errors.BzrCommandError(msg)
1257
_merge_tags_if_possible(br_from, branch)
1258
# If the source branch is stacked, the new branch may
1259
# be stacked whether we asked for that explicitly or not.
1260
# We therefore need a try/except here and not just 'if stacked:'
1262
note('Created new stacked branch referring to %s.' %
1263
branch.get_stacked_on_url())
1264
except (errors.NotStacked, errors.UnstackableBranchFormat,
1265
errors.UnstackableRepositoryFormat), e:
1266
note('Branched %d revision(s).' % branch.revno())
1268
# Switch to the new branch
1269
wt, _ = WorkingTree.open_containing('.')
1270
_mod_switch.switch(wt.bzrdir, branch)
1271
note('Switched to branch: %s',
1272
urlutils.unescape_for_display(branch.base, 'utf-8'))
1377
1277
class cmd_checkout(Command):
1378
__doc__ = """Create a new checkout of an existing branch.
1278
"""Create a new checkout of an existing branch.
1380
1280
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1381
1281
the branch found in '.'. This is useful if you have removed the working tree
1488
1389
If you want to discard your local changes, you can just do a
1489
1390
'bzr revert' instead of 'bzr commit' after the update.
1491
If you want to restore a file that has been removed locally, use
1492
'bzr revert' instead of 'bzr update'.
1494
1392
If the tree's branch is bound to a master branch, it will also update
1495
1393
the branch from the master.
1498
1396
_see_also = ['pull', 'working-trees', 'status-flags']
1499
1397
takes_args = ['dir?']
1500
takes_options = ['revision',
1502
help="Show base revision text in conflicts."),
1398
takes_options = ['revision']
1504
1399
aliases = ['up']
1506
def run(self, dir='.', revision=None, show_base=None):
1401
def run(self, dir='.', revision=None):
1507
1402
if revision is not None and len(revision) != 1:
1508
raise errors.BzrCommandError(gettext(
1509
"bzr update --revision takes exactly one revision"))
1403
raise errors.BzrCommandError(
1404
"bzr update --revision takes exactly one revision")
1510
1405
tree = WorkingTree.open_containing(dir)[0]
1511
1406
branch = tree.branch
1512
1407
possible_transports = []
1513
1408
master = branch.get_master_branch(
1514
1409
possible_transports=possible_transports)
1515
1410
if master is not None:
1516
1412
branch_location = master.base
1414
tree.lock_tree_write()
1519
1415
branch_location = tree.branch.base
1520
tree.lock_tree_write()
1521
self.add_cleanup(tree.unlock)
1522
1416
# get rid of the final '/' and be ready for display
1523
branch_location = urlutils.unescape_for_display(
1524
branch_location.rstrip('/'),
1526
existing_pending_merges = tree.get_parent_ids()[1:]
1530
# may need to fetch data into a heavyweight checkout
1531
# XXX: this may take some time, maybe we should display a
1533
old_tip = branch.update(possible_transports)
1534
if revision is not None:
1535
revision_id = revision[0].as_revision_id(branch)
1537
revision_id = branch.last_revision()
1538
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1539
revno = branch.revision_id_to_dotted_revno(revision_id)
1540
note(gettext("Tree is up to date at revision {0} of branch {1}"
1541
).format('.'.join(map(str, revno)), branch_location))
1543
view_info = _get_view_info_for_change_reporter(tree)
1544
change_reporter = delta._ChangeReporter(
1545
unversioned_filter=tree.is_ignored,
1546
view_info=view_info)
1417
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1548
conflicts = tree.update(
1550
possible_transports=possible_transports,
1551
revision=revision_id,
1553
show_base=show_base)
1554
except errors.NoSuchRevision, e:
1555
raise errors.BzrCommandError(gettext(
1556
"branch has no revision %s\n"
1557
"bzr update --revision only works"
1558
" for a revision in the branch history")
1560
revno = tree.branch.revision_id_to_dotted_revno(
1561
_mod_revision.ensure_null(tree.last_revision()))
1562
note(gettext('Updated to revision {0} of branch {1}').format(
1563
'.'.join(map(str, revno)), branch_location))
1564
parent_ids = tree.get_parent_ids()
1565
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1566
note(gettext('Your local commits will now show as pending merges with '
1567
"'bzr status', and can be committed with 'bzr commit'."))
1420
existing_pending_merges = tree.get_parent_ids()[1:]
1424
# may need to fetch data into a heavyweight checkout
1425
# XXX: this may take some time, maybe we should display a
1427
old_tip = branch.update(possible_transports)
1428
if revision is not None:
1429
revision_id = revision[0].as_revision_id(branch)
1431
revision_id = branch.last_revision()
1432
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1433
revno = branch.revision_id_to_revno(revision_id)
1434
note("Tree is up to date at revision %d of branch %s" %
1435
(revno, branch_location))
1437
view_info = _get_view_info_for_change_reporter(tree)
1438
change_reporter = delta._ChangeReporter(
1439
unversioned_filter=tree.is_ignored,
1440
view_info=view_info)
1442
conflicts = tree.update(
1444
possible_transports=possible_transports,
1445
revision=revision_id,
1447
except errors.NoSuchRevision, e:
1448
raise errors.BzrCommandError(
1449
"branch has no revision %s\n"
1450
"bzr update --revision only works"
1451
" for a revision in the branch history"
1453
revno = tree.branch.revision_id_to_revno(
1454
_mod_revision.ensure_null(tree.last_revision()))
1455
note('Updated to revision %d of branch %s' %
1456
(revno, branch_location))
1457
if tree.get_parent_ids()[1:] != existing_pending_merges:
1458
note('Your local commits will now show as pending merges with '
1459
"'bzr status', and can be committed with 'bzr commit'.")
1574
1468
class cmd_info(Command):
1575
__doc__ = """Show information about a working tree, branch or repository.
1469
"""Show information about a working tree, branch or repository.
1577
1471
This command will show all known locations and formats associated to the
1578
1472
tree, branch or repository.
1630
1523
RegistryOption.from_kwargs('file-deletion-strategy',
1631
1524
'The file deletion mode to be used.',
1632
1525
title='Deletion Strategy', value_switches=True, enum_switch=False,
1633
safe='Backup changed files (default).',
1526
safe='Only delete files if they can be'
1527
' safely recovered (default).',
1634
1528
keep='Delete from bzr but leave the working copy.',
1635
no_backup='Don\'t backup changed files.',
1636
1529
force='Delete all the specified files, even if they can not be '
1637
'recovered and even if they are non-empty directories. '
1638
'(deprecated, use no-backup)')]
1530
'recovered and even if they are non-empty directories.')]
1639
1531
aliases = ['rm', 'del']
1640
1532
encoding_type = 'replace'
1642
1534
def run(self, file_list, verbose=False, new=False,
1643
1535
file_deletion_strategy='safe'):
1644
if file_deletion_strategy == 'force':
1645
note(gettext("(The --force option is deprecated, rather use --no-backup "
1647
file_deletion_strategy = 'no-backup'
1649
tree, file_list = WorkingTree.open_containing_paths(file_list)
1536
tree, file_list = tree_files(file_list)
1651
1538
if file_list is not None:
1652
1539
file_list = [f for f in file_list]
1654
self.add_cleanup(tree.lock_write().unlock)
1655
# Heuristics should probably all move into tree.remove_smart or
1658
added = tree.changes_from(tree.basis_tree(),
1659
specific_files=file_list).added
1660
file_list = sorted([f[0] for f in added], reverse=True)
1661
if len(file_list) == 0:
1662
raise errors.BzrCommandError(gettext('No matching files.'))
1663
elif file_list is None:
1664
# missing files show up in iter_changes(basis) as
1665
# versioned-with-no-kind.
1667
for change in tree.iter_changes(tree.basis_tree()):
1668
# Find paths in the working tree that have no kind:
1669
if change[1][1] is not None and change[6][1] is None:
1670
missing.append(change[1][1])
1671
file_list = sorted(missing, reverse=True)
1672
file_deletion_strategy = 'keep'
1673
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1674
keep_files=file_deletion_strategy=='keep',
1675
force=(file_deletion_strategy=='no-backup'))
1543
# Heuristics should probably all move into tree.remove_smart or
1546
added = tree.changes_from(tree.basis_tree(),
1547
specific_files=file_list).added
1548
file_list = sorted([f[0] for f in added], reverse=True)
1549
if len(file_list) == 0:
1550
raise errors.BzrCommandError('No matching files.')
1551
elif file_list is None:
1552
# missing files show up in iter_changes(basis) as
1553
# versioned-with-no-kind.
1555
for change in tree.iter_changes(tree.basis_tree()):
1556
# Find paths in the working tree that have no kind:
1557
if change[1][1] is not None and change[6][1] is None:
1558
missing.append(change[1][1])
1559
file_list = sorted(missing, reverse=True)
1560
file_deletion_strategy = 'keep'
1561
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1562
keep_files=file_deletion_strategy=='keep',
1563
force=file_deletion_strategy=='force')
1678
1568
class cmd_file_id(Command):
1679
__doc__ = """Print file_id of a particular file or directory.
1569
"""Print file_id of a particular file or directory.
1681
1571
The file_id is assigned when the file is first added and remains the
1682
1572
same through all revisions where the file exists, even when it is
2110
1959
elif ':' in prefix:
2111
1960
old_label, new_label = prefix.split(":")
2113
raise errors.BzrCommandError(gettext(
1962
raise errors.BzrCommandError(
2114
1963
'--prefix expects two values separated by a colon'
2115
' (eg "old/:new/")'))
1964
' (eg "old/:new/")')
2117
1966
if revision and len(revision) > 2:
2118
raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
2119
' one or two revision specifiers'))
2121
if using is not None and format is not None:
2122
raise errors.BzrCommandError(gettext(
2123
'{0} and {1} are mutually exclusive').format(
2124
'--using', '--format'))
1967
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1968
' one or two revision specifiers')
2126
1970
(old_tree, new_tree,
2127
1971
old_branch, new_branch,
2128
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2129
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2130
# GNU diff on Windows uses ANSI encoding for filenames
2131
path_encoding = osutils.get_diff_header_encoding()
1972
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1973
file_list, revision, old, new, apply_view=True)
2132
1974
return show_diff_trees(old_tree, new_tree, sys.stdout,
2133
1975
specific_files=specific_files,
2134
1976
external_diff_options=diff_options,
2135
1977
old_label=old_label, new_label=new_label,
2136
extra_trees=extra_trees,
2137
path_encoding=path_encoding,
1978
extra_trees=extra_trees, using=using)
2142
1981
class cmd_deleted(Command):
2143
__doc__ = """List files deleted in the working tree.
1982
"""List files deleted in the working tree.
2145
1984
# TODO: Show files deleted since a previous revision, or
2146
1985
# between two revisions.
2149
1988
# level of effort but possibly much less IO. (Or possibly not,
2150
1989
# if the directories are very large...)
2151
1990
_see_also = ['status', 'ls']
2152
takes_options = ['directory', 'show-ids']
1991
takes_options = ['show-ids']
2154
1993
@display_command
2155
def run(self, show_ids=False, directory=u'.'):
2156
tree = WorkingTree.open_containing(directory)[0]
2157
self.add_cleanup(tree.lock_read().unlock)
2158
old = tree.basis_tree()
2159
self.add_cleanup(old.lock_read().unlock)
2160
for path, ie in old.inventory.iter_entries():
2161
if not tree.has_id(ie.file_id):
2162
self.outf.write(path)
2164
self.outf.write(' ')
2165
self.outf.write(ie.file_id)
2166
self.outf.write('\n')
1994
def run(self, show_ids=False):
1995
tree = WorkingTree.open_containing(u'.')[0]
1998
old = tree.basis_tree()
2001
for path, ie in old.inventory.iter_entries():
2002
if not tree.has_id(ie.file_id):
2003
self.outf.write(path)
2005
self.outf.write(' ')
2006
self.outf.write(ie.file_id)
2007
self.outf.write('\n')
2169
2014
class cmd_modified(Command):
2170
__doc__ = """List files modified in working tree.
2015
"""List files modified in working tree.
2174
2019
_see_also = ['status', 'ls']
2175
takes_options = ['directory', 'null']
2022
help='Write an ascii NUL (\\0) separator '
2023
'between files rather than a newline.')
2177
2026
@display_command
2178
def run(self, null=False, directory=u'.'):
2179
tree = WorkingTree.open_containing(directory)[0]
2180
self.add_cleanup(tree.lock_read().unlock)
2027
def run(self, null=False):
2028
tree = WorkingTree.open_containing(u'.')[0]
2181
2029
td = tree.changes_from(tree.basis_tree())
2183
2030
for path, id, kind, text_modified, meta_modified in td.modified:
2185
2032
self.outf.write(path + '\0')
2190
2037
class cmd_added(Command):
2191
__doc__ = """List files added in working tree.
2038
"""List files added in working tree.
2195
2042
_see_also = ['status', 'ls']
2196
takes_options = ['directory', 'null']
2045
help='Write an ascii NUL (\\0) separator '
2046
'between files rather than a newline.')
2198
2049
@display_command
2199
def run(self, null=False, directory=u'.'):
2200
wt = WorkingTree.open_containing(directory)[0]
2201
self.add_cleanup(wt.lock_read().unlock)
2202
basis = wt.basis_tree()
2203
self.add_cleanup(basis.lock_read().unlock)
2204
basis_inv = basis.inventory
2207
if basis_inv.has_id(file_id):
2209
if inv.is_root(file_id) and len(basis_inv) == 0:
2211
path = inv.id2path(file_id)
2212
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2215
self.outf.write(path + '\0')
2217
self.outf.write(osutils.quotefn(path) + '\n')
2050
def run(self, null=False):
2051
wt = WorkingTree.open_containing(u'.')[0]
2054
basis = wt.basis_tree()
2057
basis_inv = basis.inventory
2060
if file_id in basis_inv:
2062
if inv.is_root(file_id) and len(basis_inv) == 0:
2064
path = inv.id2path(file_id)
2065
if not os.access(osutils.abspath(path), os.F_OK):
2068
self.outf.write(path + '\0')
2070
self.outf.write(osutils.quotefn(path) + '\n')
2220
2077
class cmd_root(Command):
2221
__doc__ = """Show the tree root directory.
2078
"""Show the tree root directory.
2223
2080
The root is the nearest enclosing directory with a .bzr control
2491
2312
show_diff=False,
2492
include_merged=None,
2494
exclude_common_ancestry=False,
2498
match_committer=None,
2502
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2313
include_merges=False):
2504
2314
from bzrlib.log import (
2506
2316
make_log_request_dict,
2507
2317
_get_info_for_log_files,
2509
2319
direction = (forward and 'forward') or 'reverse'
2510
if symbol_versioning.deprecated_passed(include_merges):
2511
ui.ui_factory.show_user_warning(
2512
'deprecated_command_option',
2513
deprecated_name='--include-merges',
2514
recommended_name='--include-merged',
2515
deprecated_in_version='2.5',
2516
command=self.invoked_as)
2517
if include_merged is None:
2518
include_merged = include_merges
2520
raise errors.BzrCommandError(gettext(
2521
'{0} and {1} are mutually exclusive').format(
2522
'--include-merges', '--include-merged'))
2523
if include_merged is None:
2524
include_merged = False
2525
if (exclude_common_ancestry
2526
and (revision is None or len(revision) != 2)):
2527
raise errors.BzrCommandError(gettext(
2528
'--exclude-common-ancestry requires -r with two revisions'))
2530
2321
if levels is None:
2533
raise errors.BzrCommandError(gettext(
2534
'{0} and {1} are mutually exclusive').format(
2535
'--levels', '--include-merged'))
2324
raise errors.BzrCommandError(
2325
'--levels and --include-merges are mutually exclusive')
2537
2327
if change is not None:
2538
2328
if len(change) > 1:
2539
2329
raise errors.RangeInChangeOption()
2540
2330
if revision is not None:
2541
raise errors.BzrCommandError(gettext(
2542
'{0} and {1} are mutually exclusive').format(
2543
'--revision', '--change'))
2331
raise errors.BzrCommandError(
2332
'--revision and --change are mutually exclusive')
2545
2334
revision = change
2548
2337
filter_by_dir = False
2550
# find the file ids to log and check for directory filtering
2551
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2552
revision, file_list, self.add_cleanup)
2553
for relpath, file_id, kind in file_info_list:
2555
raise errors.BzrCommandError(gettext(
2556
"Path unknown at end or start of revision range: %s") %
2558
# If the relpath is the top of the tree, we log everything
2341
# find the file ids to log and check for directory filtering
2342
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2343
revision, file_list)
2344
for relpath, file_id, kind in file_info_list:
2346
raise errors.BzrCommandError(
2347
"Path unknown at end or start of revision range: %s" %
2349
# If the relpath is the top of the tree, we log everything
2354
file_ids.append(file_id)
2355
filter_by_dir = filter_by_dir or (
2356
kind in ['directory', 'tree-reference'])
2359
# FIXME ? log the current subdir only RBC 20060203
2360
if revision is not None \
2361
and len(revision) > 0 and revision[0].get_branch():
2362
location = revision[0].get_branch()
2563
file_ids.append(file_id)
2564
filter_by_dir = filter_by_dir or (
2565
kind in ['directory', 'tree-reference'])
2568
# FIXME ? log the current subdir only RBC 20060203
2569
if revision is not None \
2570
and len(revision) > 0 and revision[0].get_branch():
2571
location = revision[0].get_branch()
2574
dir, relpath = bzrdir.BzrDir.open_containing(location)
2575
b = dir.open_branch()
2576
self.add_cleanup(b.lock_read().unlock)
2577
rev1, rev2 = _get_revision_range(revision, b, self.name())
2579
if b.get_config().validate_signatures_in_log():
2583
if not gpg.GPGStrategy.verify_signatures_available():
2584
raise errors.GpgmeNotInstalled(None)
2586
# Decide on the type of delta & diff filtering to use
2587
# TODO: add an --all-files option to make this configurable & consistent
2595
diff_type = 'partial'
2599
# Build the log formatter
2600
if log_format is None:
2601
log_format = log.log_formatter_registry.get_default(b)
2602
# Make a non-encoding output to include the diffs - bug 328007
2603
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2604
lf = log_format(show_ids=show_ids, to_file=self.outf,
2605
to_exact_file=unencoded_output,
2606
show_timezone=timezone,
2607
delta_format=get_verbosity_level(),
2609
show_advice=levels is None,
2610
author_list_handler=authors)
2612
# Choose the algorithm for doing the logging. It's annoying
2613
# having multiple code paths like this but necessary until
2614
# the underlying repository format is faster at generating
2615
# deltas or can provide everything we need from the indices.
2616
# The default algorithm - match-using-deltas - works for
2617
# multiple files and directories and is faster for small
2618
# amounts of history (200 revisions say). However, it's too
2619
# slow for logging a single file in a repository with deep
2620
# history, i.e. > 10K revisions. In the spirit of "do no
2621
# evil when adding features", we continue to use the
2622
# original algorithm - per-file-graph - for the "single
2623
# file that isn't a directory without showing a delta" case.
2624
partial_history = revision and b.repository._format.supports_chks
2625
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2626
or delta_type or partial_history)
2630
match_dict[''] = match
2632
match_dict['message'] = match_message
2634
match_dict['committer'] = match_committer
2636
match_dict['author'] = match_author
2638
match_dict['bugs'] = match_bugs
2640
# Build the LogRequest and execute it
2641
if len(file_ids) == 0:
2643
rqst = make_log_request_dict(
2644
direction=direction, specific_fileids=file_ids,
2645
start_revision=rev1, end_revision=rev2, limit=limit,
2646
message_search=message, delta_type=delta_type,
2647
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2648
exclude_common_ancestry=exclude_common_ancestry, match=match_dict,
2649
signature=signatures, omit_merges=omit_merges,
2651
Logger(b, rqst).show(lf)
2365
dir, relpath = bzrdir.BzrDir.open_containing(location)
2366
b = dir.open_branch()
2368
rev1, rev2 = _get_revision_range(revision, b, self.name())
2370
# Decide on the type of delta & diff filtering to use
2371
# TODO: add an --all-files option to make this configurable & consistent
2379
diff_type = 'partial'
2383
# Build the log formatter
2384
if log_format is None:
2385
log_format = log.log_formatter_registry.get_default(b)
2386
# Make a non-encoding output to include the diffs - bug 328007
2387
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2388
lf = log_format(show_ids=show_ids, to_file=self.outf,
2389
to_exact_file=unencoded_output,
2390
show_timezone=timezone,
2391
delta_format=get_verbosity_level(),
2393
show_advice=levels is None)
2395
# Choose the algorithm for doing the logging. It's annoying
2396
# having multiple code paths like this but necessary until
2397
# the underlying repository format is faster at generating
2398
# deltas or can provide everything we need from the indices.
2399
# The default algorithm - match-using-deltas - works for
2400
# multiple files and directories and is faster for small
2401
# amounts of history (200 revisions say). However, it's too
2402
# slow for logging a single file in a repository with deep
2403
# history, i.e. > 10K revisions. In the spirit of "do no
2404
# evil when adding features", we continue to use the
2405
# original algorithm - per-file-graph - for the "single
2406
# file that isn't a directory without showing a delta" case.
2407
partial_history = revision and b.repository._format.supports_chks
2408
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2409
or delta_type or partial_history)
2411
# Build the LogRequest and execute it
2412
if len(file_ids) == 0:
2414
rqst = make_log_request_dict(
2415
direction=direction, specific_fileids=file_ids,
2416
start_revision=rev1, end_revision=rev2, limit=limit,
2417
message_search=message, delta_type=delta_type,
2418
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2419
Logger(b, rqst).show(lf)
2654
2425
def _get_revision_range(revisionspec_list, branch, command_name):
2743
2513
help='Recurse into subdirectories.'),
2744
2514
Option('from-root',
2745
2515
help='Print paths relative to the root of the branch.'),
2746
Option('unknown', short_name='u',
2747
help='Print unknown files.'),
2516
Option('unknown', help='Print unknown files.'),
2748
2517
Option('versioned', help='Print versioned files.',
2749
2518
short_name='V'),
2750
Option('ignored', short_name='i',
2751
help='Print ignored files.'),
2752
Option('kind', short_name='k',
2519
Option('ignored', help='Print ignored files.'),
2521
help='Write an ascii NUL (\\0) separator '
2522
'between files rather than a newline.'),
2753
2524
help='List entries of a particular kind: file, directory, symlink.',
2759
2528
@display_command
2760
2529
def run(self, revision=None, verbose=False,
2761
2530
recursive=False, from_root=False,
2762
2531
unknown=False, versioned=False, ignored=False,
2763
null=False, kind=None, show_ids=False, path=None, directory=None):
2532
null=False, kind=None, show_ids=False, path=None):
2765
2534
if kind and kind not in ('file', 'directory', 'symlink'):
2766
raise errors.BzrCommandError(gettext('invalid kind specified'))
2535
raise errors.BzrCommandError('invalid kind specified')
2768
2537
if verbose and null:
2769
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2538
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2770
2539
all = not (unknown or versioned or ignored)
2772
2541
selection = {'I':ignored, '?':unknown, 'V':versioned}
2799
2568
apply_view = True
2800
2569
view_str = views.view_display_str(view_files)
2801
note(gettext("Ignoring files outside view. View is %s") % view_str)
2803
self.add_cleanup(tree.lock_read().unlock)
2804
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2805
from_dir=relpath, recursive=recursive):
2806
# Apply additional masking
2807
if not all and not selection[fc]:
2809
if kind is not None and fkind != kind:
2814
fullpath = osutils.pathjoin(relpath, fp)
2817
views.check_path_in_view(tree, fullpath)
2818
except errors.FileOutsideView:
2823
fp = osutils.pathjoin(prefix, fp)
2824
kindch = entry.kind_character()
2825
outstring = fp + kindch
2826
ui.ui_factory.clear_term()
2828
outstring = '%-8s %s' % (fc, outstring)
2829
if show_ids and fid is not None:
2830
outstring = "%-50s %s" % (outstring, fid)
2831
self.outf.write(outstring + '\n')
2833
self.outf.write(fp + '\0')
2836
self.outf.write(fid)
2837
self.outf.write('\0')
2845
self.outf.write('%-50s %s\n' % (outstring, my_id))
2570
note("Ignoring files outside view. View is %s" % view_str)
2574
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2575
from_dir=relpath, recursive=recursive):
2576
# Apply additional masking
2577
if not all and not selection[fc]:
2579
if kind is not None and fkind != kind:
2584
fullpath = osutils.pathjoin(relpath, fp)
2587
views.check_path_in_view(tree, fullpath)
2588
except errors.FileOutsideView:
2593
fp = osutils.pathjoin(prefix, fp)
2594
kindch = entry.kind_character()
2595
outstring = fp + kindch
2596
ui.ui_factory.clear_term()
2598
outstring = '%-8s %s' % (fc, outstring)
2599
if show_ids and fid is not None:
2600
outstring = "%-50s %s" % (outstring, fid)
2847
2601
self.outf.write(outstring + '\n')
2603
self.outf.write(fp + '\0')
2606
self.outf.write(fid)
2607
self.outf.write('\0')
2615
self.outf.write('%-50s %s\n' % (outstring, my_id))
2617
self.outf.write(outstring + '\n')
2850
2622
class cmd_unknowns(Command):
2851
__doc__ = """List unknown files.
2623
"""List unknown files.
2855
2627
_see_also = ['ls']
2856
takes_options = ['directory']
2858
2629
@display_command
2859
def run(self, directory=u'.'):
2860
for f in WorkingTree.open_containing(directory)[0].unknowns():
2631
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2861
2632
self.outf.write(osutils.quotefn(f) + '\n')
2864
2635
class cmd_ignore(Command):
2865
__doc__ = """Ignore specified files or patterns.
2636
"""Ignore specified files or patterns.
2867
2638
See ``bzr help patterns`` for details on the syntax of patterns.
2926
2671
Ignore everything but the "debian" toplevel directory::
2928
2673
bzr ignore "RE:(?!debian/).*"
2930
Ignore everything except the "local" toplevel directory,
2931
but always ignore autosave files ending in ~, even under local/::
2934
bzr ignore "!./local"
2938
2676
_see_also = ['status', 'ignored', 'patterns']
2939
2677
takes_args = ['name_pattern*']
2940
takes_options = ['directory',
2941
Option('default-rules',
2942
help='Display the default ignore rules that bzr uses.')
2679
Option('old-default-rules',
2680
help='Write out the ignore rules bzr < 0.9 always used.')
2945
def run(self, name_pattern_list=None, default_rules=None,
2683
def run(self, name_pattern_list=None, old_default_rules=None):
2947
2684
from bzrlib import ignores
2948
if default_rules is not None:
2949
# dump the default rules and exit
2950
for pattern in ignores.USER_DEFAULTS:
2951
self.outf.write("%s\n" % pattern)
2685
if old_default_rules is not None:
2686
# dump the rules and exit
2687
for pattern in ignores.OLD_DEFAULTS:
2953
2690
if not name_pattern_list:
2954
raise errors.BzrCommandError(gettext("ignore requires at least one "
2955
"NAME_PATTERN or --default-rules."))
2691
raise errors.BzrCommandError("ignore requires at least one "
2692
"NAME_PATTERN or --old-default-rules")
2956
2693
name_pattern_list = [globbing.normalize_pattern(p)
2957
2694
for p in name_pattern_list]
2959
bad_patterns_count = 0
2960
for p in name_pattern_list:
2961
if not globbing.Globster.is_pattern_valid(p):
2962
bad_patterns_count += 1
2963
bad_patterns += ('\n %s' % p)
2965
msg = (ngettext('Invalid ignore pattern found. %s',
2966
'Invalid ignore patterns found. %s',
2967
bad_patterns_count) % bad_patterns)
2968
ui.ui_factory.show_error(msg)
2969
raise errors.InvalidPattern('')
2970
2695
for name_pattern in name_pattern_list:
2971
2696
if (name_pattern[0] == '/' or
2972
2697
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2973
raise errors.BzrCommandError(gettext(
2974
"NAME_PATTERN should not be an absolute path"))
2975
tree, relpath = WorkingTree.open_containing(directory)
2698
raise errors.BzrCommandError(
2699
"NAME_PATTERN should not be an absolute path")
2700
tree, relpath = WorkingTree.open_containing(u'.')
2976
2701
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2977
2702
ignored = globbing.Globster(name_pattern_list)
2979
self.add_cleanup(tree.lock_read().unlock)
2980
2705
for entry in tree.list_files():
2982
2707
if id is not None:
2983
2708
filename = entry[0]
2984
2709
if ignored.match(filename):
2985
matches.append(filename)
2710
matches.append(filename.encode('utf-8'))
2986
2712
if len(matches) > 0:
2987
self.outf.write(gettext("Warning: the following files are version "
2988
"controlled and match your ignore pattern:\n%s"
2989
"\nThese files will continue to be version controlled"
2990
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2713
print "Warning: the following files are version controlled and" \
2714
" match your ignore pattern:\n%s" \
2715
"\nThese files will continue to be version controlled" \
2716
" unless you 'bzr remove' them." % ("\n".join(matches),)
2993
2719
class cmd_ignored(Command):
2994
__doc__ = """List ignored files and the patterns that matched them.
2720
"""List ignored files and the patterns that matched them.
2996
2722
List all the ignored files and the ignore pattern that caused the file to
3004
2730
encoding_type = 'replace'
3005
2731
_see_also = ['ignore', 'ls']
3006
takes_options = ['directory']
3008
2733
@display_command
3009
def run(self, directory=u'.'):
3010
tree = WorkingTree.open_containing(directory)[0]
3011
self.add_cleanup(tree.lock_read().unlock)
3012
for path, file_class, kind, file_id, entry in tree.list_files():
3013
if file_class != 'I':
3015
## XXX: Slightly inefficient since this was already calculated
3016
pat = tree.is_ignored(path)
3017
self.outf.write('%-50s %s\n' % (path, pat))
2735
tree = WorkingTree.open_containing(u'.')[0]
2738
for path, file_class, kind, file_id, entry in tree.list_files():
2739
if file_class != 'I':
2741
## XXX: Slightly inefficient since this was already calculated
2742
pat = tree.is_ignored(path)
2743
self.outf.write('%-50s %s\n' % (path, pat))
3020
2748
class cmd_lookup_revision(Command):
3021
__doc__ = """Lookup the revision-id from a revision-number
2749
"""Lookup the revision-id from a revision-number
3024
2752
bzr lookup-revision 33
3027
2755
takes_args = ['revno']
3028
takes_options = ['directory']
3030
2757
@display_command
3031
def run(self, revno, directory=u'.'):
2758
def run(self, revno):
3033
2760
revno = int(revno)
3034
2761
except ValueError:
3035
raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3037
revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
3038
self.outf.write("%s\n" % revid)
2762
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2764
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
3041
2767
class cmd_export(Command):
3042
__doc__ = """Export current or past revision to a destination directory or archive.
2768
"""Export current or past revision to a destination directory or archive.
3044
2770
If no revision is specified this exports the last committed revision.
3124
2845
@display_command
3125
2846
def run(self, filename, revision=None, name_from_revision=False,
3126
filters=False, directory=None):
3127
2848
if revision is not None and len(revision) != 1:
3128
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3129
" one revision specifier"))
2849
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2850
" one revision specifier")
3130
2851
tree, branch, relpath = \
3131
_open_directory_or_containing_tree_or_branch(filename, directory)
3132
self.add_cleanup(branch.lock_read().unlock)
3133
return self._run(tree, branch, relpath, filename, revision,
3134
name_from_revision, filters)
2852
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2855
return self._run(tree, branch, relpath, filename, revision,
2856
name_from_revision, filters)
3136
2860
def _run(self, tree, b, relpath, filename, revision, name_from_revision,
3138
2862
if tree is None:
3139
2863
tree = b.basis_tree()
3140
2864
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
3141
self.add_cleanup(rev_tree.lock_read().unlock)
3143
2866
old_file_id = rev_tree.path2id(relpath)
3145
# TODO: Split out this code to something that generically finds the
3146
# best id for a path across one or more trees; it's like
3147
# find_ids_across_trees but restricted to find just one. -- mbp
3149
2868
if name_from_revision:
3150
2869
# Try in revision if requested
3151
2870
if old_file_id is None:
3152
raise errors.BzrCommandError(gettext(
3153
"{0!r} is not present in revision {1}").format(
2871
raise errors.BzrCommandError(
2872
"%r is not present in revision %s" % (
3154
2873
filename, rev_tree.get_revision_id()))
3156
actual_file_id = old_file_id
2875
content = rev_tree.get_file_text(old_file_id)
3158
2877
cur_file_id = tree.path2id(relpath)
3159
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3160
actual_file_id = cur_file_id
3161
elif old_file_id is not None:
3162
actual_file_id = old_file_id
3164
raise errors.BzrCommandError(gettext(
3165
"{0!r} is not present in revision {1}").format(
2879
if cur_file_id is not None:
2880
# Then try with the actual file id
2882
content = rev_tree.get_file_text(cur_file_id)
2884
except errors.NoSuchId:
2885
# The actual file id didn't exist at that time
2887
if not found and old_file_id is not None:
2888
# Finally try with the old file id
2889
content = rev_tree.get_file_text(old_file_id)
2892
# Can't be found anywhere
2893
raise errors.BzrCommandError(
2894
"%r is not present in revision %s" % (
3166
2895
filename, rev_tree.get_revision_id()))
3168
from bzrlib.filter_tree import ContentFilterTree
3169
filter_tree = ContentFilterTree(rev_tree,
3170
rev_tree._content_filter_stack)
3171
content = filter_tree.get_file_text(actual_file_id)
2897
from bzrlib.filters import (
2898
ContentFilterContext,
2899
filtered_output_bytes,
2901
filters = rev_tree._content_filter_stack(relpath)
2902
chunks = content.splitlines(True)
2903
content = filtered_output_bytes(chunks, filters,
2904
ContentFilterContext(relpath, rev_tree))
2905
self.outf.writelines(content)
3173
content = rev_tree.get_file_text(actual_file_id)
3175
self.outf.write(content)
2907
self.outf.write(content)
3178
2910
class cmd_local_time_offset(Command):
3179
__doc__ = """Show the offset in seconds from GMT to local time."""
2911
"""Show the offset in seconds from GMT to local time."""
3181
2913
@display_command
3183
self.outf.write("%s\n" % osutils.local_time_offset())
2915
print osutils.local_time_offset()
3187
2919
class cmd_commit(Command):
3188
__doc__ = """Commit changes into a new revision.
2920
"""Commit changes into a new revision.
3190
2922
An explanatory message needs to be given for each commit. This is
3191
2923
often done by using the --message option (getting the message from the
3274
3031
"the master branch until a normal commit "
3275
3032
"is performed."
3277
Option('show-diff', short_name='p',
3278
3035
help='When no message is supplied, show the diff along'
3279
3036
' with the status summary in the message editor.'),
3281
help='When committing to a foreign version control '
3282
'system do not push data that can not be natively '
3285
3038
aliases = ['ci', 'checkin']
3287
3040
def _iter_bug_fix_urls(self, fixes, branch):
3288
default_bugtracker = None
3289
3041
# Configure the properties for bug fixing attributes.
3290
3042
for fixed_bug in fixes:
3291
3043
tokens = fixed_bug.split(':')
3292
if len(tokens) == 1:
3293
if default_bugtracker is None:
3294
branch_config = branch.get_config()
3295
default_bugtracker = branch_config.get_user_option(
3297
if default_bugtracker is None:
3298
raise errors.BzrCommandError(gettext(
3299
"No tracker specified for bug %s. Use the form "
3300
"'tracker:id' or specify a default bug tracker "
3301
"using the `bugtracker` option.\nSee "
3302
"\"bzr help bugs\" for more information on this "
3303
"feature. Commit refused.") % fixed_bug)
3304
tag = default_bugtracker
3306
elif len(tokens) != 2:
3307
raise errors.BzrCommandError(gettext(
3044
if len(tokens) != 2:
3045
raise errors.BzrCommandError(
3308
3046
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3309
3047
"See \"bzr help bugs\" for more information on this "
3310
"feature.\nCommit refused.") % fixed_bug)
3312
tag, bug_id = tokens
3048
"feature.\nCommit refused." % fixed_bug)
3049
tag, bug_id = tokens
3314
3051
yield bugtracker.get_bug_url(tag, branch, bug_id)
3315
3052
except errors.UnknownBugTrackerAbbreviation:
3316
raise errors.BzrCommandError(gettext(
3317
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3053
raise errors.BzrCommandError(
3054
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3318
3055
except errors.MalformedBugIdentifier, e:
3319
raise errors.BzrCommandError(gettext(
3320
"%s\nCommit refused.") % (str(e),))
3056
raise errors.BzrCommandError(
3057
"%s\nCommit refused." % (str(e),))
3322
3059
def run(self, message=None, file=None, verbose=False, selected_list=None,
3323
3060
unchanged=False, strict=False, local=False, fixes=None,
3324
author=None, show_diff=False, exclude=None, commit_time=None,
3061
author=None, show_diff=False, exclude=None, commit_time=None):
3326
3062
from bzrlib.errors import (
3327
3063
PointlessCommit,
3328
3064
ConflictsInTree,
3376
3117
'(use --file "%(f)s" to take commit message from that file)'
3377
3118
% { 'f': message })
3378
3119
ui.ui_factory.show_warning(warning_msg)
3380
message = message.replace('\r\n', '\n')
3381
message = message.replace('\r', '\n')
3383
raise errors.BzrCommandError(gettext(
3384
"please specify either --message or --file"))
3386
3121
def get_message(commit_obj):
3387
3122
"""Callback to get commit message"""
3391
my_message = f.read().decode(osutils.get_user_encoding())
3394
elif message is not None:
3395
my_message = message
3397
# No message supplied: make one up.
3398
# text is the status of the tree
3399
text = make_commit_message_template_encoded(tree,
3123
my_message = message
3124
if my_message is not None and '\r' in my_message:
3125
my_message = my_message.replace('\r\n', '\n')
3126
my_message = my_message.replace('\r', '\n')
3127
if my_message is None and not file:
3128
t = make_commit_message_template_encoded(tree,
3400
3129
selected_list, diff=show_diff,
3401
3130
output_encoding=osutils.get_user_encoding())
3402
# start_message is the template generated from hooks
3403
# XXX: Warning - looks like hooks return unicode,
3404
# make_commit_message_template_encoded returns user encoding.
3405
# We probably want to be using edit_commit_message instead to
3407
my_message = set_commit_message(commit_obj)
3408
if my_message is None:
3409
start_message = generate_commit_message_template(commit_obj)
3410
my_message = edit_commit_message_encoded(text,
3411
start_message=start_message)
3412
if my_message is None:
3413
raise errors.BzrCommandError(gettext("please specify a commit"
3414
" message with either --message or --file"))
3415
if my_message == "":
3416
raise errors.BzrCommandError(gettext("Empty commit message specified."
3417
" Please specify a commit message with either"
3418
" --message or --file or leave a blank message"
3419
" with --message \"\"."))
3131
start_message = generate_commit_message_template(commit_obj)
3132
my_message = edit_commit_message_encoded(t,
3133
start_message=start_message)
3134
if my_message is None:
3135
raise errors.BzrCommandError("please specify a commit"
3136
" message with either --message or --file")
3137
elif my_message and file:
3138
raise errors.BzrCommandError(
3139
"please specify either --message or --file")
3141
my_message = codecs.open(file, 'rt',
3142
osutils.get_user_encoding()).read()
3143
if my_message == "":
3144
raise errors.BzrCommandError("empty commit message specified")
3420
3145
return my_message
3422
3147
# The API permits a commit with a filter of [] to mean 'select nothing'
3430
3155
reporter=None, verbose=verbose, revprops=properties,
3431
3156
authors=author, timestamp=commit_stamp,
3432
3157
timezone=offset,
3433
exclude=tree.safe_relpath_files(exclude),
3158
exclude=safe_relpath_files(tree, exclude))
3435
3159
except PointlessCommit:
3436
raise errors.BzrCommandError(gettext("No changes to commit."
3437
" Please 'bzr add' the files you want to commit, or use"
3438
" --unchanged to force an empty commit."))
3160
# FIXME: This should really happen before the file is read in;
3161
# perhaps prepare the commit; get the message; then actually commit
3162
raise errors.BzrCommandError("No changes to commit."
3163
" Use --unchanged to commit anyhow.")
3439
3164
except ConflictsInTree:
3440
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3165
raise errors.BzrCommandError('Conflicts detected in working '
3441
3166
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3443
3168
except StrictCommitFailed:
3444
raise errors.BzrCommandError(gettext("Commit refused because there are"
3445
" unknown files in the working tree."))
3169
raise errors.BzrCommandError("Commit refused because there are"
3170
" unknown files in the working tree.")
3446
3171
except errors.BoundBranchOutOfDate, e:
3447
e.extra_help = (gettext("\n"
3448
'To commit to master branch, run update and then commit.\n'
3449
'You can also pass --local to commit to continue working '
3172
raise errors.BzrCommandError(str(e) + "\n"
3173
'To commit to master branch, run update and then commit.\n'
3174
'You can also pass --local to commit to continue working '
3454
3178
class cmd_check(Command):
3455
__doc__ = """Validate working tree structure, branch consistency and repository history.
3179
"""Validate working tree structure, branch consistency and repository history.
3457
3181
This command checks various invariants about branch and repository storage
3458
3182
to detect data corruption or bzr bugs.
3524
3248
class cmd_upgrade(Command):
3525
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3527
When the default format has changed after a major new release of
3528
Bazaar, you may be informed during certain operations that you
3529
should upgrade. Upgrading to a newer format may improve performance
3530
or make new features available. It may however limit interoperability
3531
with older repositories or with older versions of Bazaar.
3533
If you wish to upgrade to a particular format rather than the
3534
current default, that can be specified using the --format option.
3535
As a consequence, you can use the upgrade command this way to
3536
"downgrade" to an earlier format, though some conversions are
3537
a one way process (e.g. changing from the 1.x default to the
3538
2.x default) so downgrading is not always possible.
3540
A backup.bzr.~#~ directory is created at the start of the conversion
3541
process (where # is a number). By default, this is left there on
3542
completion. If the conversion fails, delete the new .bzr directory
3543
and rename this one back in its place. Use the --clean option to ask
3544
for the backup.bzr directory to be removed on successful conversion.
3545
Alternatively, you can delete it by hand if everything looks good
3548
If the location given is a shared repository, dependent branches
3549
are also converted provided the repository converts successfully.
3550
If the conversion of a branch fails, remaining branches are still
3553
For more information on upgrades, see the Bazaar Upgrade Guide,
3554
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3249
"""Upgrade branch storage to current format.
3251
The check command or bzr developers may sometimes advise you to run
3252
this command. When the default format has changed you may also be warned
3253
during other operations to upgrade.
3557
_see_also = ['check', 'reconcile', 'formats']
3256
_see_also = ['check']
3558
3257
takes_args = ['url?']
3559
3258
takes_options = [
3560
RegistryOption('format',
3561
help='Upgrade to a specific format. See "bzr help'
3562
' formats" for details.',
3563
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3564
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3565
value_switches=True, title='Branch format'),
3567
help='Remove the backup.bzr directory if successful.'),
3569
help="Show what would be done, but don't actually do anything."),
3259
RegistryOption('format',
3260
help='Upgrade to a specific format. See "bzr help'
3261
' formats" for details.',
3262
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3263
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3264
value_switches=True, title='Branch format'),
3572
def run(self, url='.', format=None, clean=False, dry_run=False):
3267
def run(self, url='.', format=None):
3573
3268
from bzrlib.upgrade import upgrade
3574
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3576
if len(exceptions) == 1:
3577
# Compatibility with historical behavior
3269
upgrade(url, format)
3583
3272
class cmd_whoami(Command):
3584
__doc__ = """Show or set bzr user id.
3273
"""Show or set bzr user id.
3587
3276
Show the email of the current user::
3603
3291
encoding_type = 'replace'
3605
3293
@display_command
3606
def run(self, email=False, branch=False, name=None, directory=None):
3294
def run(self, email=False, branch=False, name=None):
3607
3295
if name is None:
3608
if directory is None:
3609
# use branch if we're inside one; otherwise global config
3611
c = Branch.open_containing(u'.')[0].get_config()
3612
except errors.NotBranchError:
3613
c = _mod_config.GlobalConfig()
3615
c = Branch.open(directory).get_config()
3296
# use branch if we're inside one; otherwise global config
3298
c = Branch.open_containing('.')[0].get_config()
3299
except errors.NotBranchError:
3300
c = config.GlobalConfig()
3617
3302
self.outf.write(c.user_email() + '\n')
3619
3304
self.outf.write(c.username() + '\n')
3623
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3626
3307
# display a warning if an email address isn't included in the given name.
3628
_mod_config.extract_email_address(name)
3309
config.extract_email_address(name)
3629
3310
except errors.NoEmailInUsername, e:
3630
3311
warning('"%s" does not seem to contain an email address. '
3631
3312
'This is allowed, but not recommended.', name)
3633
3314
# use global config unless --branch given
3635
if directory is None:
3636
c = Branch.open_containing(u'.')[0].get_config()
3638
c = Branch.open(directory).get_config()
3316
c = Branch.open_containing('.')[0].get_config()
3640
c = _mod_config.GlobalConfig()
3318
c = config.GlobalConfig()
3641
3319
c.set_user_option('email', name)
3644
3322
class cmd_nick(Command):
3645
__doc__ = """Print or set the branch nickname.
3323
"""Print or set the branch nickname.
3647
3325
If unset, the tree root directory name is used as the nickname.
3648
3326
To print the current nickname, execute with no argument.
3880
3559
from bzrlib.tests import SubUnitBzrRunner
3881
3560
except ImportError:
3882
raise errors.BzrCommandError(gettext("subunit not available. subunit "
3883
"needs to be installed to use --subunit."))
3561
raise errors.BzrCommandError("subunit not available. subunit "
3562
"needs to be installed to use --subunit.")
3884
3563
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3885
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3886
# stdout, which would corrupt the subunit stream.
3887
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3888
# following code can be deleted when it's sufficiently deployed
3889
# -- vila/mgz 20100514
3890
if (sys.platform == "win32"
3891
and getattr(sys.stdout, 'fileno', None) is not None):
3893
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3895
3565
self.additional_selftest_args.setdefault(
3896
3566
'suite_decorators', []).append(parallel)
3898
raise errors.BzrCommandError(gettext(
3899
"--benchmark is no longer supported from bzr 2.2; "
3900
"use bzr-usertest instead"))
3901
test_suite_factory = None
3903
exclude_pattern = None
3568
test_suite_factory = benchmarks.test_suite
3569
# Unless user explicitly asks for quiet, be verbose in benchmarks
3570
verbose = not is_quiet()
3571
# TODO: should possibly lock the history file...
3572
benchfile = open(".perf_history", "at", buffering=1)
3905
exclude_pattern = '(' + '|'.join(exclude) + ')'
3907
self._disable_fsync()
3908
selftest_kwargs = {"verbose": verbose,
3910
"stop_on_failure": one,
3911
"transport": transport,
3912
"test_suite_factory": test_suite_factory,
3913
"lsprof_timed": lsprof_timed,
3914
"lsprof_tests": lsprof_tests,
3915
"matching_tests_first": first,
3916
"list_only": list_only,
3917
"random_seed": randomize,
3918
"exclude_pattern": exclude_pattern,
3920
"load_list": load_list,
3921
"debug_flags": debugflag,
3922
"starting_with": starting_with
3924
selftest_kwargs.update(self.additional_selftest_args)
3926
# Make deprecation warnings visible, unless -Werror is set
3927
cleanup = symbol_versioning.activate_deprecation_warnings(
3574
test_suite_factory = None
3930
result = tests.selftest(**selftest_kwargs)
3577
selftest_kwargs = {"verbose": verbose,
3579
"stop_on_failure": one,
3580
"transport": transport,
3581
"test_suite_factory": test_suite_factory,
3582
"lsprof_timed": lsprof_timed,
3583
"lsprof_tests": lsprof_tests,
3584
"bench_history": benchfile,
3585
"matching_tests_first": first,
3586
"list_only": list_only,
3587
"random_seed": randomize,
3588
"exclude_pattern": exclude,
3590
"load_list": load_list,
3591
"debug_flags": debugflag,
3592
"starting_with": starting_with
3594
selftest_kwargs.update(self.additional_selftest_args)
3595
result = selftest(**selftest_kwargs)
3597
if benchfile is not None:
3933
3599
return int(not result)
3935
def _disable_fsync(self):
3936
"""Change the 'os' functionality to not synchronize."""
3937
self._orig_fsync = getattr(os, 'fsync', None)
3938
if self._orig_fsync is not None:
3939
os.fsync = lambda filedes: None
3940
self._orig_fdatasync = getattr(os, 'fdatasync', None)
3941
if self._orig_fdatasync is not None:
3942
os.fdatasync = lambda filedes: None
3945
3602
class cmd_version(Command):
3946
__doc__ = """Show version of bzr."""
3603
"""Show version of bzr."""
3948
3605
encoding_type = 'replace'
3949
3606
takes_options = [
3983
3640
branch1 = Branch.open_containing(branch)[0]
3984
3641
branch2 = Branch.open_containing(other)[0]
3985
self.add_cleanup(branch1.lock_read().unlock)
3986
self.add_cleanup(branch2.lock_read().unlock)
3987
last1 = ensure_null(branch1.last_revision())
3988
last2 = ensure_null(branch2.last_revision())
3990
graph = branch1.repository.get_graph(branch2.repository)
3991
base_rev_id = graph.find_unique_lca(last1, last2)
3993
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3646
last1 = ensure_null(branch1.last_revision())
3647
last2 = ensure_null(branch2.last_revision())
3649
graph = branch1.repository.get_graph(branch2.repository)
3650
base_rev_id = graph.find_unique_lca(last1, last2)
3652
print 'merge base is revision %s' % base_rev_id
3996
3659
class cmd_merge(Command):
3997
__doc__ = """Perform a three-way merge.
3660
"""Perform a three-way merge.
3999
3662
The source of the merge can be specified either in the form of a branch,
4000
3663
or in the form of a path to a file containing a merge directive generated
4001
3664
with bzr send. If neither is specified, the default is the upstream branch
4002
or the branch most recently merged using --remember. The source of the
4003
merge may also be specified in the form of a path to a file in another
4004
branch: in this case, only the modifications to that file are merged into
4005
the current working tree.
4007
When merging from a branch, by default bzr will try to merge in all new
4008
work from the other branch, automatically determining an appropriate base
4009
revision. If this fails, you may need to give an explicit base.
4011
To pick a different ending revision, pass "--revision OTHER". bzr will
4012
try to merge in all new work up to and including revision OTHER.
4014
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4015
through OTHER, excluding BASE but including OTHER, will be merged. If this
4016
causes some revisions to be skipped, i.e. if the destination branch does
4017
not already contain revision BASE, such a merge is commonly referred to as
4018
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4019
cherrypicks. The changes look like a normal commit, and the history of the
4020
changes from the other branch is not stored in the commit.
4022
Revision numbers are always relative to the source branch.
3665
or the branch most recently merged using --remember.
3667
When merging a branch, by default the tip will be merged. To pick a different
3668
revision, pass --revision. If you specify two values, the first will be used as
3669
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3670
available revisions, like this is commonly referred to as "cherrypicking".
3672
Revision numbers are always relative to the branch being merged.
3674
By default, bzr will try to merge in all new work from the other
3675
branch, automatically determining an appropriate base. If this
3676
fails, you may need to give an explicit base.
4024
3678
Merge will do its best to combine the changes in two branches, but there
4025
3679
are some kinds of problems only a human can fix. When it encounters those,
4029
3683
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
4031
If there is no default branch set, the first merge will set it (use
4032
--no-remember to avoid setting it). After that, you can omit the branch
4033
to use the default. To change the default, use --remember. The value will
4034
only be saved if the remote location can be accessed.
3685
If there is no default branch set, the first merge will set it. After
3686
that, you can omit the branch to use the default. To change the
3687
default, use --remember. The value will only be saved if the remote
3688
location can be accessed.
4036
3690
The results of the merge are placed into the destination working
4037
3691
directory, where they can be reviewed (with bzr diff), tested, and then
4038
3692
committed to record the result of the merge.
4040
3694
merge refuses to run if there are any uncommitted changes, unless
4041
--force is given. If --force is given, then the changes from the source
4042
will be merged with the current working tree, including any uncommitted
4043
changes in the tree. The --force option can also be used to create a
4044
merge revision which has more than two parents.
4046
If one would like to merge changes from the working tree of the other
4047
branch without merging any committed revisions, the --uncommitted option
4050
3697
To select only some changes to merge, use "merge -i", which will prompt
4051
3698
you to apply each diff hunk and file change, similar to "shelve".
4054
To merge all new revisions from bzr.dev::
3701
To merge the latest revision from bzr.dev::
4056
3703
bzr merge ../bzr.dev
4137
3776
view_info = _get_view_info_for_change_reporter(tree)
4138
3777
change_reporter = delta._ChangeReporter(
4139
3778
unversioned_filter=tree.is_ignored, view_info=view_info)
4140
pb = ui.ui_factory.nested_progress_bar()
4141
self.add_cleanup(pb.finished)
4142
self.add_cleanup(tree.lock_write().unlock)
4143
if location is not None:
4145
mergeable = bundle.read_mergeable_from_url(location,
4146
possible_transports=possible_transports)
4147
except errors.NotABundle:
3781
pb = ui.ui_factory.nested_progress_bar()
3782
cleanups.append(pb.finished)
3784
cleanups.append(tree.unlock)
3785
if location is not None:
3787
mergeable = bundle.read_mergeable_from_url(location,
3788
possible_transports=possible_transports)
3789
except errors.NotABundle:
3793
raise errors.BzrCommandError('Cannot use --uncommitted'
3794
' with bundles or merge directives.')
3796
if revision is not None:
3797
raise errors.BzrCommandError(
3798
'Cannot use -r with merge directives or bundles')
3799
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3802
if merger is None and uncommitted:
3803
if revision is not None and len(revision) > 0:
3804
raise errors.BzrCommandError('Cannot use --uncommitted and'
3805
' --revision at the same time.')
3806
merger = self.get_merger_from_uncommitted(tree, location, pb,
3808
allow_pending = False
3811
merger, allow_pending = self._get_merger_from_branch(tree,
3812
location, revision, remember, possible_transports, pb)
3814
merger.merge_type = merge_type
3815
merger.reprocess = reprocess
3816
merger.show_base = show_base
3817
self.sanity_check_merger(merger)
3818
if (merger.base_rev_id == merger.other_rev_id and
3819
merger.other_rev_id is not None):
3820
note('Nothing to do.')
3823
if merger.interesting_files is not None:
3824
raise errors.BzrCommandError('Cannot pull individual files')
3825
if (merger.base_rev_id == tree.last_revision()):
3826
result = tree.pull(merger.other_branch, False,
3827
merger.other_rev_id)
3828
result.report(self.outf)
3830
if merger.this_basis is None:
3831
raise errors.BzrCommandError(
3832
"This branch has no commits."
3833
" (perhaps you would prefer 'bzr pull')")
3835
return self._do_preview(merger, cleanups)
3837
return self._do_interactive(merger, cleanups)
4151
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4152
' with bundles or merge directives.'))
4154
if revision is not None:
4155
raise errors.BzrCommandError(gettext(
4156
'Cannot use -r with merge directives or bundles'))
4157
merger, verified = _mod_merge.Merger.from_mergeable(tree,
4160
if merger is None and uncommitted:
4161
if revision is not None and len(revision) > 0:
4162
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4163
' --revision at the same time.'))
4164
merger = self.get_merger_from_uncommitted(tree, location, None)
4165
allow_pending = False
4168
merger, allow_pending = self._get_merger_from_branch(tree,
4169
location, revision, remember, possible_transports, None)
4171
merger.merge_type = merge_type
4172
merger.reprocess = reprocess
4173
merger.show_base = show_base
4174
self.sanity_check_merger(merger)
4175
if (merger.base_rev_id == merger.other_rev_id and
4176
merger.other_rev_id is not None):
4177
# check if location is a nonexistent file (and not a branch) to
4178
# disambiguate the 'Nothing to do'
4179
if merger.interesting_files:
4180
if not merger.other_tree.has_filename(
4181
merger.interesting_files[0]):
4182
note(gettext("merger: ") + str(merger))
4183
raise errors.PathsDoNotExist([location])
4184
note(gettext('Nothing to do.'))
4186
if pull and not preview:
4187
if merger.interesting_files is not None:
4188
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4189
if (merger.base_rev_id == tree.last_revision()):
4190
result = tree.pull(merger.other_branch, False,
4191
merger.other_rev_id)
4192
result.report(self.outf)
4194
if merger.this_basis is None:
4195
raise errors.BzrCommandError(gettext(
4196
"This branch has no commits."
4197
" (perhaps you would prefer 'bzr pull')"))
4199
return self._do_preview(merger)
4201
return self._do_interactive(merger)
4203
return self._do_merge(merger, change_reporter, allow_pending,
4206
def _get_preview(self, merger):
3839
return self._do_merge(merger, change_reporter, allow_pending,
3842
for cleanup in reversed(cleanups):
3845
def _get_preview(self, merger, cleanups):
4207
3846
tree_merger = merger.make_merger()
4208
3847
tt = tree_merger.make_preview_transform()
4209
self.add_cleanup(tt.finalize)
3848
cleanups.append(tt.finalize)
4210
3849
result_tree = tt.get_preview_tree()
4211
3850
return result_tree
4213
def _do_preview(self, merger):
3852
def _do_preview(self, merger, cleanups):
4214
3853
from bzrlib.diff import show_diff_trees
4215
result_tree = self._get_preview(merger)
4216
path_encoding = osutils.get_diff_header_encoding()
3854
result_tree = self._get_preview(merger, cleanups)
4217
3855
show_diff_trees(merger.this_tree, result_tree, self.outf,
4218
old_label='', new_label='',
4219
path_encoding=path_encoding)
3856
old_label='', new_label='')
4221
3858
def _do_merge(self, merger, change_reporter, allow_pending, verified):
4222
3859
merger.change_reporter = change_reporter
4415
4046
def run(self, file_list=None, merge_type=None, show_base=False,
4416
4047
reprocess=False):
4417
from bzrlib.conflicts import restore
4418
4048
if merge_type is None:
4419
4049
merge_type = _mod_merge.Merge3Merger
4420
tree, file_list = WorkingTree.open_containing_paths(file_list)
4421
self.add_cleanup(tree.lock_write().unlock)
4422
parents = tree.get_parent_ids()
4423
if len(parents) != 2:
4424
raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4425
" merges. Not cherrypicking or"
4427
repository = tree.branch.repository
4428
interesting_ids = None
4430
conflicts = tree.conflicts()
4431
if file_list is not None:
4432
interesting_ids = set()
4433
for filename in file_list:
4434
file_id = tree.path2id(filename)
4436
raise errors.NotVersionedError(filename)
4437
interesting_ids.add(file_id)
4438
if tree.kind(file_id) != "directory":
4050
tree, file_list = tree_files(file_list)
4053
parents = tree.get_parent_ids()
4054
if len(parents) != 2:
4055
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4056
" merges. Not cherrypicking or"
4058
repository = tree.branch.repository
4059
interesting_ids = None
4061
conflicts = tree.conflicts()
4062
if file_list is not None:
4063
interesting_ids = set()
4064
for filename in file_list:
4065
file_id = tree.path2id(filename)
4067
raise errors.NotVersionedError(filename)
4068
interesting_ids.add(file_id)
4069
if tree.kind(file_id) != "directory":
4441
for name, ie in tree.inventory.iter_entries(file_id):
4442
interesting_ids.add(ie.file_id)
4443
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4445
# Remerge only supports resolving contents conflicts
4446
allowed_conflicts = ('text conflict', 'contents conflict')
4447
restore_files = [c.path for c in conflicts
4448
if c.typestring in allowed_conflicts]
4449
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4450
tree.set_conflicts(ConflictList(new_conflicts))
4451
if file_list is not None:
4452
restore_files = file_list
4453
for filename in restore_files:
4072
for name, ie in tree.inventory.iter_entries(file_id):
4073
interesting_ids.add(ie.file_id)
4074
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4076
# Remerge only supports resolving contents conflicts
4077
allowed_conflicts = ('text conflict', 'contents conflict')
4078
restore_files = [c.path for c in conflicts
4079
if c.typestring in allowed_conflicts]
4080
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4081
tree.set_conflicts(ConflictList(new_conflicts))
4082
if file_list is not None:
4083
restore_files = file_list
4084
for filename in restore_files:
4086
restore(tree.abspath(filename))
4087
except errors.NotConflicted:
4089
# Disable pending merges, because the file texts we are remerging
4090
# have not had those merges performed. If we use the wrong parents
4091
# list, we imply that the working tree text has seen and rejected
4092
# all the changes from the other tree, when in fact those changes
4093
# have not yet been seen.
4094
pb = ui.ui_factory.nested_progress_bar()
4095
tree.set_parent_ids(parents[:1])
4455
restore(tree.abspath(filename))
4456
except errors.NotConflicted:
4458
# Disable pending merges, because the file texts we are remerging
4459
# have not had those merges performed. If we use the wrong parents
4460
# list, we imply that the working tree text has seen and rejected
4461
# all the changes from the other tree, when in fact those changes
4462
# have not yet been seen.
4463
tree.set_parent_ids(parents[:1])
4465
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4466
merger.interesting_ids = interesting_ids
4467
merger.merge_type = merge_type
4468
merger.show_base = show_base
4469
merger.reprocess = reprocess
4470
conflicts = merger.do_merge()
4097
merger = _mod_merge.Merger.from_revision_ids(pb,
4099
merger.interesting_ids = interesting_ids
4100
merger.merge_type = merge_type
4101
merger.show_base = show_base
4102
merger.reprocess = reprocess
4103
conflicts = merger.do_merge()
4105
tree.set_parent_ids(parents)
4472
tree.set_parent_ids(parents)
4473
4109
if conflicts > 0:
4503
4138
created as above. Directories containing unknown files will not be
4506
The working tree contains a list of revisions that have been merged but
4507
not yet committed. These revisions will be included as additional parents
4508
of the next commit. Normally, using revert clears that list as well as
4509
reverting the files. If any files are specified, revert leaves the list
4510
of uncommitted merges alone and reverts only the files. Use ``bzr revert
4511
.`` in the tree root to revert all files but keep the recorded merges,
4512
and ``bzr revert --forget-merges`` to clear the pending merge list without
4141
The working tree contains a list of pending merged revisions, which will
4142
be included as parents in the next commit. Normally, revert clears that
4143
list as well as reverting the files. If any files are specified, revert
4144
leaves the pending merge list alone and reverts only the files. Use "bzr
4145
revert ." in the tree root to revert all files but keep the merge record,
4146
and "bzr revert --forget-merges" to clear the pending merge list without
4513
4147
reverting any files.
4515
Using "bzr revert --forget-merges", it is possible to apply all of the
4516
changes from a branch in a single revision. To do this, perform the merge
4517
as desired. Then doing revert with the "--forget-merges" option will keep
4518
the content of the tree as it was, but it will clear the list of pending
4519
merges. The next commit will then contain all of the changes that are
4520
present in the other branch, but without any other parent revisions.
4521
Because this technique forgets where these changes originated, it may
4522
cause additional conflicts on later merges involving the same source and
4149
Using "bzr revert --forget-merges", it is possible to apply the changes
4150
from an arbitrary merge as a single revision. To do this, perform the
4151
merge as desired. Then doing revert with the "--forget-merges" option will
4152
keep the content of the tree as it was, but it will clear the list of
4153
pending merges. The next commit will then contain all of the changes that
4154
would have been in the merge, but without any mention of the other parent
4155
revisions. Because this technique forgets where these changes originated,
4156
it may cause additional conflicts on later merges involving the source and
4523
4157
target branches.
4526
_see_also = ['cat', 'export', 'merge', 'shelve']
4160
_see_also = ['cat', 'export']
4527
4161
takes_options = [
4529
4163
Option('no-backup', "Do not save backups of reverted files."),
4724
4341
_get_revision_range(revision,
4725
4342
remote_branch, self.name()))
4727
local_extra, remote_extra = find_unmerged(
4728
local_branch, remote_branch, restrict,
4729
backward=not reverse,
4730
include_merged=include_merged,
4731
local_revid_range=local_revid_range,
4732
remote_revid_range=remote_revid_range)
4734
if log_format is None:
4735
registry = log.log_formatter_registry
4736
log_format = registry.get_default(local_branch)
4737
lf = log_format(to_file=self.outf,
4739
show_timezone='original')
4742
if local_extra and not theirs_only:
4743
message(ngettext("You have %d extra revision:\n",
4744
"You have %d extra revisions:\n",
4747
for revision in iter_log_revisions(local_extra,
4748
local_branch.repository,
4750
lf.log_revision(revision)
4751
printed_local = True
4754
printed_local = False
4756
if remote_extra and not mine_only:
4757
if printed_local is True:
4759
message(ngettext("You are missing %d revision:\n",
4760
"You are missing %d revisions:\n",
4761
len(remote_extra)) %
4763
for revision in iter_log_revisions(remote_extra,
4764
remote_branch.repository,
4766
lf.log_revision(revision)
4769
if mine_only and not local_extra:
4770
# We checked local, and found nothing extra
4771
message(gettext('This branch has no new revisions.\n'))
4772
elif theirs_only and not remote_extra:
4773
# We checked remote, and found nothing extra
4774
message(gettext('Other branch has no new revisions.\n'))
4775
elif not (mine_only or theirs_only or local_extra or
4777
# We checked both branches, and neither one had extra
4779
message(gettext("Branches are up to date.\n"))
4344
local_branch.lock_read()
4346
remote_branch.lock_read()
4348
local_extra, remote_extra = find_unmerged(
4349
local_branch, remote_branch, restrict,
4350
backward=not reverse,
4351
include_merges=include_merges,
4352
local_revid_range=local_revid_range,
4353
remote_revid_range=remote_revid_range)
4355
if log_format is None:
4356
registry = log.log_formatter_registry
4357
log_format = registry.get_default(local_branch)
4358
lf = log_format(to_file=self.outf,
4360
show_timezone='original')
4363
if local_extra and not theirs_only:
4364
message("You have %d extra revision(s):\n" %
4366
for revision in iter_log_revisions(local_extra,
4367
local_branch.repository,
4369
lf.log_revision(revision)
4370
printed_local = True
4373
printed_local = False
4375
if remote_extra and not mine_only:
4376
if printed_local is True:
4378
message("You are missing %d revision(s):\n" %
4380
for revision in iter_log_revisions(remote_extra,
4381
remote_branch.repository,
4383
lf.log_revision(revision)
4386
if mine_only and not local_extra:
4387
# We checked local, and found nothing extra
4388
message('This branch is up to date.\n')
4389
elif theirs_only and not remote_extra:
4390
# We checked remote, and found nothing extra
4391
message('Other branch is up to date.\n')
4392
elif not (mine_only or theirs_only or local_extra or
4394
# We checked both branches, and neither one had extra
4396
message("Branches are up to date.\n")
4398
remote_branch.unlock()
4400
local_branch.unlock()
4781
4401
if not status_code and parent is None and other_branch is not None:
4782
self.add_cleanup(local_branch.lock_write().unlock)
4783
# handle race conditions - a parent might be set while we run.
4784
if local_branch.get_parent() is None:
4785
local_branch.set_parent(remote_branch.base)
4402
local_branch.lock_write()
4404
# handle race conditions - a parent might be set while we run.
4405
if local_branch.get_parent() is None:
4406
local_branch.set_parent(remote_branch.base)
4408
local_branch.unlock()
4786
4409
return status_code
4789
4412
class cmd_pack(Command):
4790
__doc__ = """Compress the data within a repository.
4792
This operation compresses the data within a bazaar repository. As
4793
bazaar supports automatic packing of repository, this operation is
4794
normally not required to be done manually.
4796
During the pack operation, bazaar takes a backup of existing repository
4797
data, i.e. pack files. This backup is eventually removed by bazaar
4798
automatically when it is safe to do so. To save disk space by removing
4799
the backed up pack files, the --clean-obsolete-packs option may be
4802
Warning: If you use --clean-obsolete-packs and your machine crashes
4803
during or immediately after repacking, you may be left with a state
4804
where the deletion has been written to disk but the new packs have not
4805
been. In this case the repository may be unusable.
4413
"""Compress the data within a repository."""
4808
4415
_see_also = ['repositories']
4809
4416
takes_args = ['branch_or_repo?']
4811
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4814
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4418
def run(self, branch_or_repo='.'):
4815
4419
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4817
4421
branch = dir.open_branch()
4818
4422
repository = branch.repository
4819
4423
except errors.NotBranchError:
4820
4424
repository = dir.open_repository()
4821
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4824
4428
class cmd_plugins(Command):
4825
__doc__ = """List the installed plugins.
4429
"""List the installed plugins.
4827
4431
This command displays the list of installed plugins including
4828
4432
version of plugin and a short description of each.
4835
4439
adding new commands, providing additional network transports and
4836
4440
customizing log output.
4838
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4839
for further information on plugins including where to find them and how to
4840
install them. Instructions are also provided there on how to write new
4841
plugins using the Python programming language.
4442
See the Bazaar web site, http://bazaar-vcs.org, for further
4443
information on plugins including where to find them and how to
4444
install them. Instructions are also provided there on how to
4445
write new plugins using the Python programming language.
4843
4447
takes_options = ['verbose']
4845
4449
@display_command
4846
4450
def run(self, verbose=False):
4847
from bzrlib import plugin
4848
# Don't give writelines a generator as some codecs don't like that
4849
self.outf.writelines(
4850
list(plugin.describe_plugins(show_paths=verbose)))
4451
import bzrlib.plugin
4452
from inspect import getdoc
4454
for name, plugin in bzrlib.plugin.plugins().items():
4455
version = plugin.__version__
4456
if version == 'unknown':
4458
name_ver = '%s %s' % (name, version)
4459
d = getdoc(plugin.module)
4461
doc = d.split('\n')[0]
4463
doc = '(no description)'
4464
result.append((name_ver, doc, plugin.path()))
4465
for name_ver, doc, path in sorted(result):
4853
4473
class cmd_testament(Command):
4854
__doc__ = """Show testament (signing-form) of a revision."""
4474
"""Show testament (signing-form) of a revision."""
4855
4475
takes_options = [
4857
4477
Option('long', help='Produce long-format testament.'),
4899
4522
Option('long', help='Show commit date in annotations.'),
4904
4526
encoding_type = 'exact'
4906
4528
@display_command
4907
4529
def run(self, filename, all=False, long=False, revision=None,
4908
show_ids=False, directory=None):
4909
from bzrlib.annotate import (
4531
from bzrlib.annotate import annotate_file, annotate_file_tree
4912
4532
wt, branch, relpath = \
4913
_open_directory_or_containing_tree_or_branch(filename, directory)
4533
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4914
4534
if wt is not None:
4915
self.add_cleanup(wt.lock_read().unlock)
4917
self.add_cleanup(branch.lock_read().unlock)
4918
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4919
self.add_cleanup(tree.lock_read().unlock)
4920
if wt is not None and revision is None:
4921
file_id = wt.path2id(relpath)
4923
file_id = tree.path2id(relpath)
4925
raise errors.NotVersionedError(filename)
4926
if wt is not None and revision is None:
4927
# If there is a tree and we're not annotating historical
4928
# versions, annotate the working tree's content.
4929
annotate_file_tree(wt, file_id, self.outf, long, all,
4932
annotate_file_tree(tree, file_id, self.outf, long, all,
4933
show_ids=show_ids, branch=branch)
4539
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4541
file_id = wt.path2id(relpath)
4543
file_id = tree.path2id(relpath)
4545
raise errors.NotVersionedError(filename)
4546
file_version = tree.inventory[file_id].revision
4547
if wt is not None and revision is None:
4548
# If there is a tree and we're not annotating historical
4549
# versions, annotate the working tree's content.
4550
annotate_file_tree(wt, file_id, self.outf, long, all,
4553
annotate_file(branch, file_version, file_id, long, all, self.outf,
4936
4562
class cmd_re_sign(Command):
4937
__doc__ = """Create a digital signature for an existing revision."""
4563
"""Create a digital signature for an existing revision."""
4938
4564
# TODO be able to replace existing ones.
4940
4566
hidden = True # is this right ?
4941
4567
takes_args = ['revision_id*']
4942
takes_options = ['directory', 'revision']
4568
takes_options = ['revision']
4944
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4570
def run(self, revision_id_list=None, revision=None):
4945
4571
if revision_id_list is not None and revision is not None:
4946
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4572
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4947
4573
if revision_id_list is None and revision is None:
4948
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
4949
b = WorkingTree.open_containing(directory)[0].branch
4950
self.add_cleanup(b.lock_write().unlock)
4951
return self._run(b, revision_id_list, revision)
4574
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4575
b = WorkingTree.open_containing(u'.')[0].branch
4578
return self._run(b, revision_id_list, revision)
4953
4582
def _run(self, b, revision_id_list, revision):
4954
4583
import bzrlib.gpg as gpg
5013
4641
_see_also = ['checkouts', 'unbind']
5014
4642
takes_args = ['location?']
5015
takes_options = ['directory']
5017
def run(self, location=None, directory=u'.'):
5018
b, relpath = Branch.open_containing(directory)
4645
def run(self, location=None):
4646
b, relpath = Branch.open_containing(u'.')
5019
4647
if location is None:
5021
4649
location = b.get_old_bound_location()
5022
4650
except errors.UpgradeRequired:
5023
raise errors.BzrCommandError(gettext('No location supplied. '
5024
'This format does not remember old locations.'))
4651
raise errors.BzrCommandError('No location supplied. '
4652
'This format does not remember old locations.')
5026
4654
if location is None:
5027
if b.get_bound_location() is not None:
5028
raise errors.BzrCommandError(gettext('Branch is already bound'))
5030
raise errors.BzrCommandError(gettext('No location supplied '
5031
'and no previous location known'))
4655
raise errors.BzrCommandError('No location supplied and no '
4656
'previous location known')
5032
4657
b_other = Branch.open(location)
5034
4659
b.bind(b_other)
5035
4660
except errors.DivergedBranches:
5036
raise errors.BzrCommandError(gettext('These branches have diverged.'
5037
' Try merging, and then bind again.'))
4661
raise errors.BzrCommandError('These branches have diverged.'
4662
' Try merging, and then bind again.')
5038
4663
if b.get_config().has_explicit_nickname():
5039
4664
b.nick = b_other.nick
5042
4667
class cmd_unbind(Command):
5043
__doc__ = """Convert the current checkout into a regular branch.
4668
"""Convert the current checkout into a regular branch.
5045
4670
After unbinding, the local branch is considered independent and subsequent
5046
4671
commits will be local only.
5147
4776
end_revision=last_revno)
5150
self.outf.write(gettext('Dry-run, pretending to remove'
5151
' the above revisions.\n'))
4779
print 'Dry-run, pretending to remove the above revisions.'
4781
val = raw_input('Press <enter> to continue')
5153
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5156
if not ui.ui_factory.confirm_action(
5157
gettext(u'Uncommit these revisions'),
5158
'bzrlib.builtins.uncommit',
5160
self.outf.write(gettext('Canceled\n'))
4783
print 'The above revision(s) will be removed.'
4785
val = raw_input('Are you sure [y/N]? ')
4786
if val.lower() not in ('y', 'yes'):
5163
4790
mutter('Uncommitting from {%s} to {%s}',
5164
4791
last_rev_id, rev_id)
5165
4792
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5166
revno=revno, local=local, keep_tags=keep_tags)
5167
self.outf.write(gettext('You can restore the old tip by running:\n'
5168
' bzr pull . -r revid:%s\n') % last_rev_id)
4793
revno=revno, local=local)
4794
note('You can restore the old tip by running:\n'
4795
' bzr pull . -r revid:%s', last_rev_id)
5171
4798
class cmd_break_lock(Command):
5172
__doc__ = """Break a dead lock.
5174
This command breaks a lock on a repository, branch, working directory or
4799
"""Break a dead lock on a repository, branch or working directory.
5177
4801
CAUTION: Locks should only be broken when you are sure that the process
5178
4802
holding the lock has been stopped.
5180
You can get information on what locks are open via the 'bzr info
5181
[location]' command.
4804
You can get information on what locks are open via the 'bzr info' command.
5185
bzr break-lock bzr+ssh://example.com/bzr/foo
5186
bzr break-lock --conf ~/.bazaar
5189
4809
takes_args = ['location?']
5192
help='LOCATION is the directory where the config lock is.'),
5194
help='Do not ask for confirmation before breaking the lock.'),
5197
def run(self, location=None, config=False, force=False):
4811
def run(self, location=None, show=False):
5198
4812
if location is None:
5199
4813
location = u'.'
5201
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5203
{'bzrlib.lockdir.break': True})
5205
conf = _mod_config.LockableConfig(file_name=location)
5208
control, relpath = bzrdir.BzrDir.open_containing(location)
5210
control.break_lock()
5211
except NotImplementedError:
4814
control, relpath = bzrdir.BzrDir.open_containing(location)
4816
control.break_lock()
4817
except NotImplementedError:
5215
4821
class cmd_wait_until_signalled(Command):
5216
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4822
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5218
4824
This just prints a line to signal when it is ready, then blocks on stdin.
5279
4884
return host, port
5281
4886
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5282
protocol=None, client_timeout=None):
5283
from bzrlib import transport
4888
from bzrlib.transport import get_transport, transport_server_registry
5284
4889
if directory is None:
5285
4890
directory = os.getcwd()
5286
4891
if protocol is None:
5287
protocol = transport.transport_server_registry.get()
4892
protocol = transport_server_registry.get()
5288
4893
host, port = self.get_host_and_port(port)
5289
4894
url = urlutils.local_path_to_url(directory)
5290
4895
if not allow_writes:
5291
4896
url = 'readonly+' + url
5292
t = transport.get_transport(url)
5294
protocol(t, host, port, inet, client_timeout)
5295
except TypeError, e:
5296
# We use symbol_versioning.deprecated_in just so that people
5297
# grepping can find it here.
5298
# symbol_versioning.deprecated_in((2, 5, 0))
5299
symbol_versioning.warn(
5300
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5301
'Most likely it needs to be updated to support a'
5302
' "timeout" parameter (added in bzr 2.5.0)'
5303
% (e, protocol.__module__, protocol),
5305
protocol(t, host, port, inet)
4897
transport = get_transport(url)
4898
protocol(transport, host, port, inet)
5308
4901
class cmd_join(Command):
5309
__doc__ = """Combine a tree into its containing tree.
4902
"""Combine a tree into its containing tree.
5311
4904
This command requires the target tree to be in a rich-root format.
5491
5082
directly from the merge directive, without retrieving data from a
5494
`bzr send` creates a compact data set that, when applied using bzr
5495
merge, has the same effect as merging from the source branch.
5497
By default the merge directive is self-contained and can be applied to any
5498
branch containing submit_branch in its ancestory without needing access to
5501
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5502
revisions, but only a structured request to merge from the
5503
public_location. In that case the public_branch is needed and it must be
5504
up-to-date and accessible to the recipient. The public_branch is always
5505
included if known, so that people can check it later.
5507
The submit branch defaults to the parent of the source branch, but can be
5508
overridden. Both submit branch and public branch will be remembered in
5509
branch.conf the first time they are used for a particular branch. The
5510
source branch defaults to that containing the working directory, but can
5511
be changed using --from.
5513
Both the submit branch and the public branch follow the usual behavior with
5514
respect to --remember: If there is no default location set, the first send
5515
will set it (use --no-remember to avoid setting it). After that, you can
5516
omit the location to use the default. To change the default, use
5517
--remember. The value will only be saved if the location can be accessed.
5519
In order to calculate those changes, bzr must analyse the submit branch.
5520
Therefore it is most efficient for the submit branch to be a local mirror.
5521
If a public location is known for the submit_branch, that location is used
5522
in the merge directive.
5524
The default behaviour is to send the merge directive by mail, unless -o is
5525
given, in which case it is sent to a file.
5085
If --no-bundle is specified, then public_branch is needed (and must be
5086
up-to-date), so that the receiver can perform the merge using the
5087
public_branch. The public_branch is always included if known, so that
5088
people can check it later.
5090
The submit branch defaults to the parent, but can be overridden. Both
5091
submit branch and public branch will be remembered if supplied.
5093
If a public_branch is known for the submit_branch, that public submit
5094
branch is used in the merge instructions. This means that a local mirror
5095
can be used as your actual submit branch, once you have set public_branch
5527
5098
Mail is sent using your preferred mail program. This should be transparent
5528
on Windows (it uses MAPI). On Unix, it requires the xdg-email utility.
5099
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5529
5100
If the preferred client can't be found (or used), your editor will be used.
5531
5102
To use a specific mail program, set the mail_client configuration option.
5690
5257
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5691
5258
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5693
If no tag name is specified it will be determined through the
5694
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5695
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5699
5261
_see_also = ['commit', 'tags']
5700
takes_args = ['tag_name?']
5262
takes_args = ['tag_name']
5701
5263
takes_options = [
5702
5264
Option('delete',
5703
5265
help='Delete this tag rather than placing it.',
5705
custom_help('directory',
5706
help='Branch in which to place the tag.'),
5268
help='Branch in which to place the tag.',
5707
5272
Option('force',
5708
5273
help='Replace existing tags.',
5713
def run(self, tag_name=None,
5278
def run(self, tag_name,
5719
5284
branch, relpath = Branch.open_containing(directory)
5720
self.add_cleanup(branch.lock_write().unlock)
5722
if tag_name is None:
5723
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5724
branch.tags.delete_tag(tag_name)
5725
note(gettext('Deleted tag %s.') % tag_name)
5728
if len(revision) != 1:
5729
raise errors.BzrCommandError(gettext(
5730
"Tags can only be placed on a single revision, "
5732
revision_id = revision[0].as_revision_id(branch)
5734
revision_id = branch.last_revision()
5735
if tag_name is None:
5736
tag_name = branch.automatic_tag_name(revision_id)
5737
if tag_name is None:
5738
raise errors.BzrCommandError(gettext(
5739
"Please specify a tag name."))
5741
existing_target = branch.tags.lookup_tag(tag_name)
5742
except errors.NoSuchTag:
5743
existing_target = None
5744
if not force and existing_target not in (None, revision_id):
5745
raise errors.TagAlreadyExists(tag_name)
5746
if existing_target == revision_id:
5747
note(gettext('Tag %s already exists for that revision.') % tag_name)
5288
branch.tags.delete_tag(tag_name)
5289
self.outf.write('Deleted tag %s.\n' % tag_name)
5292
if len(revision) != 1:
5293
raise errors.BzrCommandError(
5294
"Tags can only be placed on a single revision, "
5296
revision_id = revision[0].as_revision_id(branch)
5298
revision_id = branch.last_revision()
5299
if (not force) and branch.tags.has_tag(tag_name):
5300
raise errors.TagAlreadyExists(tag_name)
5749
5301
branch.tags.set_tag(tag_name, revision_id)
5750
if existing_target is None:
5751
note(gettext('Created tag %s.') % tag_name)
5753
note(gettext('Updated tag %s.') % tag_name)
5302
self.outf.write('Created tag %s.\n' % tag_name)
5756
5307
class cmd_tags(Command):
5757
__doc__ = """List tags.
5759
5310
This command shows a table of tag names and the revisions they reference.
5762
5313
_see_also = ['tag']
5763
5314
takes_options = [
5764
custom_help('directory',
5765
help='Branch whose tags should be displayed.'),
5766
RegistryOption('sort',
5316
help='Branch whose tags should be displayed.',
5320
RegistryOption.from_kwargs('sort',
5767
5321
'Sort tags by different criteria.', title='Sorting',
5768
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5322
alpha='Sort tags lexicographically (default).',
5323
time='Sort tags chronologically.',
5774
5329
@display_command
5775
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5776
from bzrlib.tag import tag_sort_methods
5777
5336
branch, relpath = Branch.open_containing(directory)
5779
5338
tags = branch.tags.get_tag_dict().items()
5783
self.add_cleanup(branch.lock_read().unlock)
5785
# Restrict to the specified range
5786
tags = self._tags_for_range(branch, revision)
5788
sort = tag_sort_methods.get()
5791
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5792
for index, (tag, revid) in enumerate(tags):
5794
revno = branch.revision_id_to_dotted_revno(revid)
5795
if isinstance(revno, tuple):
5796
revno = '.'.join(map(str, revno))
5797
except (errors.NoSuchRevision,
5798
errors.GhostRevisionsHaveNoRevno):
5799
# Bad tag data/merges can lead to tagged revisions
5800
# which are not in this branch. Fail gracefully ...
5802
tags[index] = (tag, revno)
5345
graph = branch.repository.get_graph()
5346
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5347
revid1, revid2 = rev1.rev_id, rev2.rev_id
5348
# only show revisions between revid1 and revid2 (inclusive)
5349
tags = [(tag, revid) for tag, revid in tags if
5350
graph.is_between(revid, revid1, revid2)]
5353
elif sort == 'time':
5355
for tag, revid in tags:
5357
revobj = branch.repository.get_revision(revid)
5358
except errors.NoSuchRevision:
5359
timestamp = sys.maxint # place them at the end
5361
timestamp = revobj.timestamp
5362
timestamps[revid] = timestamp
5363
tags.sort(key=lambda x: timestamps[x[1]])
5365
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5366
for index, (tag, revid) in enumerate(tags):
5368
revno = branch.revision_id_to_dotted_revno(revid)
5369
if isinstance(revno, tuple):
5370
revno = '.'.join(map(str, revno))
5371
except errors.NoSuchRevision:
5372
# Bad tag data/merges can lead to tagged revisions
5373
# which are not in this branch. Fail gracefully ...
5375
tags[index] = (tag, revno)
5804
5378
for tag, revspec in tags:
5805
5379
self.outf.write('%-20s %s\n' % (tag, revspec))
5807
def _tags_for_range(self, branch, revision):
5809
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5810
revid1, revid2 = rev1.rev_id, rev2.rev_id
5811
# _get_revision_range will always set revid2 if it's not specified.
5812
# If revid1 is None, it means we want to start from the branch
5813
# origin which is always a valid ancestor. If revid1 == revid2, the
5814
# ancestry check is useless.
5815
if revid1 and revid1 != revid2:
5816
# FIXME: We really want to use the same graph than
5817
# branch.iter_merge_sorted_revisions below, but this is not
5818
# easily available -- vila 2011-09-23
5819
if branch.repository.get_graph().is_ancestor(revid2, revid1):
5820
# We don't want to output anything in this case...
5822
# only show revisions between revid1 and revid2 (inclusive)
5823
tagged_revids = branch.tags.get_reverse_tag_dict()
5825
for r in branch.iter_merge_sorted_revisions(
5826
start_revision_id=revid2, stop_revision_id=revid1,
5827
stop_rule='include'):
5828
revid_tags = tagged_revids.get(r[0], None)
5830
found.extend([(tag, r[0]) for tag in revid_tags])
5834
5382
class cmd_reconfigure(Command):
5835
__doc__ = """Reconfigure the type of a bzr directory.
5383
"""Reconfigure the type of a bzr directory.
5837
5385
A target configuration must be specified.
5849
5397
takes_args = ['location?']
5850
5398
takes_options = [
5851
5399
RegistryOption.from_kwargs(
5854
help='The relation between branch and tree.',
5401
title='Target type',
5402
help='The type to reconfigure the directory to.',
5855
5403
value_switches=True, enum_switch=False,
5856
5404
branch='Reconfigure to be an unbound branch with no working tree.',
5857
5405
tree='Reconfigure to be an unbound branch with a working tree.',
5858
5406
checkout='Reconfigure to be a bound branch with a working tree.',
5859
5407
lightweight_checkout='Reconfigure to be a lightweight'
5860
5408
' checkout (with no local history).',
5862
RegistryOption.from_kwargs(
5864
title='Repository type',
5865
help='Location fo the repository.',
5866
value_switches=True, enum_switch=False,
5867
5409
standalone='Reconfigure to be a standalone branch '
5868
5410
'(i.e. stop using shared repository).',
5869
5411
use_shared='Reconfigure to use a shared repository.',
5871
RegistryOption.from_kwargs(
5873
title='Trees in Repository',
5874
help='Whether new branches in the repository have trees.',
5875
value_switches=True, enum_switch=False,
5876
5412
with_trees='Reconfigure repository to create '
5877
5413
'working trees on branches by default.',
5878
5414
with_no_trees='Reconfigure repository to not create '
5905
5441
# At the moment you can use --stacked-on and a different
5906
5442
# reconfiguration shape at the same time; there seems no good reason
5908
if (tree_type is None and
5909
repository_type is None and
5910
repository_trees is None):
5444
if target_type is None:
5911
5445
if stacked_on or unstacked:
5914
raise errors.BzrCommandError(gettext('No target configuration '
5916
reconfiguration = None
5917
if tree_type == 'branch':
5448
raise errors.BzrCommandError('No target configuration '
5450
elif target_type == 'branch':
5918
5451
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5919
elif tree_type == 'tree':
5452
elif target_type == 'tree':
5920
5453
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5921
elif tree_type == 'checkout':
5454
elif target_type == 'checkout':
5922
5455
reconfiguration = reconfigure.Reconfigure.to_checkout(
5923
5456
directory, bind_to)
5924
elif tree_type == 'lightweight-checkout':
5457
elif target_type == 'lightweight-checkout':
5925
5458
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5926
5459
directory, bind_to)
5928
reconfiguration.apply(force)
5929
reconfiguration = None
5930
if repository_type == 'use-shared':
5460
elif target_type == 'use-shared':
5931
5461
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5932
elif repository_type == 'standalone':
5462
elif target_type == 'standalone':
5933
5463
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5935
reconfiguration.apply(force)
5936
reconfiguration = None
5937
if repository_trees == 'with-trees':
5464
elif target_type == 'with-trees':
5938
5465
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5939
5466
directory, True)
5940
elif repository_trees == 'with-no-trees':
5467
elif target_type == 'with-no-trees':
5941
5468
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5942
5469
directory, False)
5944
reconfiguration.apply(force)
5945
reconfiguration = None
5470
reconfiguration.apply(force)
5948
5473
class cmd_switch(Command):
5949
__doc__ = """Set the branch of a checkout and update.
5474
"""Set the branch of a checkout and update.
5951
5476
For lightweight checkouts, this changes the branch being referenced.
5952
5477
For heavyweight checkouts, this checks that there are no local commits
6132
tree, file_list = WorkingTree.open_containing_paths(file_list,
5653
tree, file_list = tree_files(file_list, apply_view=False)
6134
5654
current_view, view_dict = tree.views.get_view_info()
6135
5655
if name is None:
6136
5656
name = current_view
6139
raise errors.BzrCommandError(gettext(
6140
"Both --delete and a file list specified"))
5659
raise errors.BzrCommandError(
5660
"Both --delete and a file list specified")
6142
raise errors.BzrCommandError(gettext(
6143
"Both --delete and --switch specified"))
5662
raise errors.BzrCommandError(
5663
"Both --delete and --switch specified")
6145
5665
tree.views.set_view_info(None, {})
6146
self.outf.write(gettext("Deleted all views.\n"))
5666
self.outf.write("Deleted all views.\n")
6147
5667
elif name is None:
6148
raise errors.BzrCommandError(gettext("No current view to delete"))
5668
raise errors.BzrCommandError("No current view to delete")
6150
5670
tree.views.delete_view(name)
6151
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5671
self.outf.write("Deleted '%s' view.\n" % name)
6154
raise errors.BzrCommandError(gettext(
6155
"Both --switch and a file list specified"))
5674
raise errors.BzrCommandError(
5675
"Both --switch and a file list specified")
6157
raise errors.BzrCommandError(gettext(
6158
"Both --switch and --all specified"))
5677
raise errors.BzrCommandError(
5678
"Both --switch and --all specified")
6159
5679
elif switch == 'off':
6160
5680
if current_view is None:
6161
raise errors.BzrCommandError(gettext("No current view to disable"))
5681
raise errors.BzrCommandError("No current view to disable")
6162
5682
tree.views.set_view_info(None, view_dict)
6163
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5683
self.outf.write("Disabled '%s' view.\n" % (current_view))
6165
5685
tree.views.set_view_info(switch, view_dict)
6166
5686
view_str = views.view_display_str(tree.views.lookup_view())
6167
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5687
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6170
self.outf.write(gettext('Views defined:\n'))
5690
self.outf.write('Views defined:\n')
6171
5691
for view in sorted(view_dict):
6172
5692
if view == current_view:
6446
5925
self.outf.write('%s %s\n' % (path, location))
6449
class cmd_export_pot(Command):
6450
__doc__ = """Export command helps and error messages in po format."""
6455
from bzrlib.export_pot import export_pot
6456
export_pot(self.outf)
6459
def _register_lazy_builtins():
6460
# register lazy builtins from other modules; called at startup and should
6461
# be only called once.
6462
for (name, aliases, module_name) in [
6463
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6464
('cmd_config', [], 'bzrlib.config'),
6465
('cmd_dpush', [], 'bzrlib.foreign'),
6466
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6467
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6468
('cmd_conflicts', [], 'bzrlib.conflicts'),
6469
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6470
('cmd_verify_signatures', [],
6471
'bzrlib.commit_signature_commands'),
6472
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6474
builtin_command_registry.register_lazy(name, aliases, module_name)
5928
# these get imported and then picked up by the scan for cmd_*
5929
# TODO: Some more consistent way to split command definitions across files;
5930
# we do need to load at least some information about them to know of
5931
# aliases. ideally we would avoid loading the implementation until the
5932
# details were needed.
5933
from bzrlib.cmd_version_info import cmd_version_info
5934
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5935
from bzrlib.bundle.commands import (
5938
from bzrlib.foreign import cmd_dpush
5939
from bzrlib.sign_my_commits import cmd_sign_my_commits
5940
from bzrlib.weave_commands import cmd_versionedfile_list, \
5941
cmd_weave_plan_merge, cmd_weave_merge_text