167
178
:return: workingtree, [relative_paths]
169
if file_list is None or len(file_list) == 0:
170
tree = WorkingTree.open_containing(default_branch)[0]
171
if tree.supports_views() and apply_view:
172
view_files = tree.views.lookup_view()
174
file_list = view_files
175
view_str = views.view_display_str(view_files)
176
note("Ignoring files outside view. View is %s" % view_str)
177
return tree, file_list
178
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
179
return tree, safe_relpath_files(tree, file_list, canonicalize,
180
apply_view=apply_view)
183
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
184
"""Convert file_list into a list of relpaths in tree.
186
:param tree: A tree to operate on.
187
:param file_list: A list of user provided paths or None.
188
:param apply_view: if True and a view is set, apply it or check that
189
specified files are within it
190
:return: A list of relative paths.
191
:raises errors.PathNotChild: When a provided path is in a different tree
194
if file_list is None:
196
if tree.supports_views() and apply_view:
197
view_files = tree.views.lookup_view()
201
# tree.relpath exists as a "thunk" to osutils, but canonical_relpath
202
# doesn't - fix that up here before we enter the loop.
204
fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
207
for filename in file_list:
209
relpath = fixer(osutils.dereference_path(filename))
210
if view_files and not osutils.is_inside_any(view_files, relpath):
211
raise errors.FileOutsideView(filename, view_files)
212
new_list.append(relpath)
213
except errors.PathNotChild:
214
raise errors.FileInWrongBranch(tree.branch, filename)
180
return WorkingTree.open_containing_paths(
181
file_list, default_directory='.',
218
186
def _get_view_info_for_change_reporter(tree):
337
323
takes_args = ['revision_id?']
338
takes_options = ['revision']
324
takes_options = ['directory', 'revision']
339
325
# cat-revision is more for frontends so should be exact
340
326
encoding = 'strict'
328
def print_revision(self, revisions, revid):
329
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
330
record = stream.next()
331
if record.storage_kind == 'absent':
332
raise errors.NoSuchRevision(revisions, revid)
333
revtext = record.get_bytes_as('fulltext')
334
self.outf.write(revtext.decode('utf-8'))
343
def run(self, revision_id=None, revision=None):
337
def run(self, revision_id=None, revision=None, directory=u'.'):
344
338
if revision_id is not None and revision is not None:
345
raise errors.BzrCommandError('You can only supply one of'
346
' revision_id or --revision')
339
raise errors.BzrCommandError(gettext('You can only supply one of'
340
' revision_id or --revision'))
347
341
if revision_id is None and revision is None:
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'))
342
raise errors.BzrCommandError(gettext('You must supply either'
343
' --revision or a revision_id'))
345
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
347
revisions = b.repository.revisions
348
if revisions is None:
349
raise errors.BzrCommandError(gettext('Repository %r does not support '
350
'access to raw revision texts'))
352
b.repository.lock_read()
354
# TODO: jam 20060112 should cat-revision always output utf-8?
355
if revision_id is not None:
356
revision_id = osutils.safe_revision_id(revision_id, warn=False)
358
self.print_revision(revisions, revision_id)
359
except errors.NoSuchRevision:
360
msg = gettext("The repository {0} contains no revision {1}.").format(
361
b.repository.base, revision_id)
362
raise errors.BzrCommandError(msg)
363
elif revision is not None:
366
raise errors.BzrCommandError(
367
gettext('You cannot specify a NULL revision.'))
368
rev_id = rev.as_revision_id(b)
369
self.print_revision(revisions, rev_id)
371
b.repository.unlock()
370
374
class cmd_dump_btree(Command):
371
"""Dump the contents of a btree index file to stdout.
375
__doc__ = """Dump the contents of a btree index file to stdout.
373
377
PATH is a btree index file, it can be any URL. This includes things like
374
378
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
452
464
To re-create the working tree, use "bzr checkout".
454
466
_see_also = ['checkout', 'working-trees']
455
takes_args = ['location?']
467
takes_args = ['location*']
456
468
takes_options = [
458
470
help='Remove the working tree even if it has '
459
'uncommitted changes.'),
471
'uncommitted or shelved changes.'),
462
def run(self, location='.', force=False):
463
d = bzrdir.BzrDir.open(location)
474
def run(self, location_list, force=False):
475
if not location_list:
478
for location in location_list:
479
d = controldir.ControlDir.open(location)
482
working = d.open_workingtree()
483
except errors.NoWorkingTree:
484
raise errors.BzrCommandError(gettext("No working tree to remove"))
485
except errors.NotLocalUrl:
486
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
487
" of a remote path"))
489
if (working.has_changes()):
490
raise errors.UncommittedChanges(working)
491
if working.get_shelf_manager().last_shelf() is not None:
492
raise errors.ShelvedChanges(working)
494
if working.user_url != working.branch.user_url:
495
raise errors.BzrCommandError(gettext("You cannot remove the working tree"
496
" from a lightweight checkout"))
498
d.destroy_workingtree()
501
class cmd_repair_workingtree(Command):
502
__doc__ = """Reset the working tree state file.
504
This is not meant to be used normally, but more as a way to recover from
505
filesystem corruption, etc. This rebuilds the working inventory back to a
506
'known good' state. Any new modifications (adding a file, renaming, etc)
507
will be lost, though modified files will still be detected as such.
509
Most users will want something more like "bzr revert" or "bzr update"
510
unless the state file has become corrupted.
512
By default this attempts to recover the current state by looking at the
513
headers of the state file. If the state file is too corrupted to even do
514
that, you can supply --revision to force the state of the tree.
517
takes_options = ['revision', 'directory',
519
help='Reset the tree even if it doesn\'t appear to be'
524
def run(self, revision=None, directory='.', force=False):
525
tree, _ = WorkingTree.open_containing(directory)
526
self.add_cleanup(tree.lock_tree_write().unlock)
530
except errors.BzrError:
531
pass # There seems to be a real error here, so we'll reset
534
raise errors.BzrCommandError(gettext(
535
'The tree does not appear to be corrupt. You probably'
536
' want "bzr revert" instead. Use "--force" if you are'
537
' sure you want to reset the working tree.'))
541
revision_ids = [r.as_revision_id(tree.branch) for r in revision]
466
working = d.open_workingtree()
467
except errors.NoWorkingTree:
468
raise errors.BzrCommandError("No working tree to remove")
469
except errors.NotLocalUrl:
470
raise errors.BzrCommandError("You cannot remove the working tree"
473
if (working.has_changes()):
474
raise errors.UncommittedChanges(working)
476
working_path = working.bzrdir.root_transport.base
477
branch_path = working.branch.bzrdir.root_transport.base
478
if working_path != branch_path:
479
raise errors.BzrCommandError("You cannot remove the working tree"
480
" from a lightweight checkout")
482
d.destroy_workingtree()
543
tree.reset_state(revision_ids)
544
except errors.BzrError, e:
545
if revision_ids is None:
546
extra = (gettext(', the header appears corrupt, try passing -r -1'
547
' to set the state to the last commit'))
550
raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
485
553
class cmd_revno(Command):
486
"""Show current revision number.
554
__doc__ = """Show current revision number.
488
556
This is equal to the number of revisions on this branch.
491
559
_see_also = ['info']
492
560
takes_args = ['location?']
493
561
takes_options = [
494
Option('tree', help='Show revno of working tree'),
562
Option('tree', help='Show revno of working tree.'),
498
def run(self, tree=False, location=u'.'):
567
def run(self, tree=False, location=u'.', revision=None):
568
if revision is not None and tree:
569
raise errors.BzrCommandError(gettext("--tree and --revision can "
570
"not be used together"))
501
574
wt = WorkingTree.open_containing(location)[0]
575
self.add_cleanup(wt.lock_read().unlock)
503
576
except (errors.NoWorkingTree, errors.NotLocalUrl):
504
577
raise errors.NoWorkingTree(location)
505
self.add_cleanup(wt.unlock)
506
579
revid = wt.last_revision()
508
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
509
except errors.NoSuchRevision:
511
revno = ".".join(str(n) for n in revno_t)
513
581
b = Branch.open_containing(location)[0]
515
self.add_cleanup(b.unlock)
582
self.add_cleanup(b.lock_read().unlock)
584
if len(revision) != 1:
585
raise errors.BzrCommandError(gettext(
586
"Tags can only be placed on a single revision, "
588
revid = revision[0].as_revision_id(b)
590
revid = b.last_revision()
592
revno_t = b.revision_id_to_dotted_revno(revid)
593
except errors.NoSuchRevision:
595
revno = ".".join(str(n) for n in revno_t)
517
596
self.cleanup_now()
518
self.outf.write(str(revno) + '\n')
597
self.outf.write(revno + '\n')
521
600
class cmd_revision_info(Command):
522
"""Show revision number and revision id for a given revision identifier.
601
__doc__ = """Show revision number and revision id for a given revision identifier.
525
604
takes_args = ['revision_info*']
526
605
takes_options = [
607
custom_help('directory',
529
608
help='Branch to examine, '
530
'rather than the one containing the working directory.',
534
Option('tree', help='Show revno of working tree'),
609
'rather than the one containing the working directory.'),
610
Option('tree', help='Show revno of working tree.'),
663
743
for glob in sorted(ignored.keys()):
664
744
for path in ignored[glob]:
665
self.outf.write("ignored %s matching \"%s\"\n"
746
gettext("ignored {0} matching \"{1}\"\n").format(
669
750
class cmd_mkdir(Command):
670
"""Create a new versioned directory.
751
__doc__ = """Create a new versioned directory.
672
753
This is equivalent to creating the directory and then adding it.
675
756
takes_args = ['dir+']
760
help='No error if existing, make parent directories as needed.',
676
764
encoding_type = 'replace'
678
def run(self, dir_list):
681
wt, dd = WorkingTree.open_containing(d)
683
self.outf.write('added %s\n' % d)
767
def add_file_with_parents(cls, wt, relpath):
768
if wt.path2id(relpath) is not None:
770
cls.add_file_with_parents(wt, osutils.dirname(relpath))
774
def add_file_single(cls, wt, relpath):
777
def run(self, dir_list, parents=False):
779
add_file = self.add_file_with_parents
781
add_file = self.add_file_single
783
wt, relpath = WorkingTree.open_containing(dir)
788
if e.errno != errno.EEXIST:
792
add_file(wt, relpath)
794
self.outf.write(gettext('added %s\n') % dir)
686
797
class cmd_relpath(Command):
687
"""Show path of a file relative to root"""
798
__doc__ = """Show path of a file relative to root"""
689
800
takes_args = ['filename']
723
834
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
724
835
if kind and kind not in ['file', 'directory', 'symlink']:
725
raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
836
raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
727
838
revision = _get_one_revision('inventory', revision)
728
work_tree, file_list = tree_files(file_list)
729
work_tree.lock_read()
730
self.add_cleanup(work_tree.unlock)
839
work_tree, file_list = WorkingTree.open_containing_paths(file_list)
840
self.add_cleanup(work_tree.lock_read().unlock)
731
841
if revision is not None:
732
842
tree = revision.as_tree(work_tree.branch)
734
844
extra_trees = [work_tree]
736
self.add_cleanup(tree.unlock)
845
self.add_cleanup(tree.lock_read().unlock)
794
904
return self.run_auto(names_list, after, dry_run)
796
raise errors.BzrCommandError('--dry-run requires --auto.')
906
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
797
907
if names_list is None:
799
909
if len(names_list) < 2:
800
raise errors.BzrCommandError("missing file argument")
801
tree, rel_names = tree_files(names_list, canonicalize=False)
802
tree.lock_tree_write()
803
self.add_cleanup(tree.unlock)
910
raise errors.BzrCommandError(gettext("missing file argument"))
911
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
912
for file_name in rel_names[0:-1]:
914
raise errors.BzrCommandError(gettext("can not move root of branch"))
915
self.add_cleanup(tree.lock_tree_write().unlock)
804
916
self._run(tree, names_list, rel_names, after)
806
918
def run_auto(self, names_list, after, dry_run):
807
919
if names_list is not None and len(names_list) > 1:
808
raise errors.BzrCommandError('Only one path may be specified to'
920
raise errors.BzrCommandError(gettext('Only one path may be specified to'
811
raise errors.BzrCommandError('--after cannot be specified with'
813
work_tree, file_list = tree_files(names_list, default_branch='.')
814
work_tree.lock_tree_write()
815
self.add_cleanup(work_tree.unlock)
923
raise errors.BzrCommandError(gettext('--after cannot be specified with'
925
work_tree, file_list = WorkingTree.open_containing_paths(
926
names_list, default_directory='.')
927
self.add_cleanup(work_tree.lock_tree_write().unlock)
816
928
rename_map.RenameMap.guess_renames(work_tree, dry_run)
818
930
def _run(self, tree, names_list, rel_names, after):
912
1024
match the remote one, use pull --overwrite. This will work even if the two
913
1025
branches have diverged.
915
If there is no default location set, the first pull will set it. After
916
that, you can omit the location to use the default. To change the
917
default, use --remember. The value will only be saved if the remote
918
location can be accessed.
1027
If there is no default location set, the first pull will set it (use
1028
--no-remember to avoid setting it). After that, you can omit the
1029
location to use the default. To change the default, use --remember. The
1030
value will only be saved if the remote location can be accessed.
1032
The --verbose option will display the revisions pulled using the log_format
1033
configuration option. You can use a different format by overriding it with
1034
-Olog_format=<other_format>.
920
1036
Note: The location can be specified either in the form of a branch,
921
1037
or in the form of a path to a file containing a merge directive generated
926
1042
takes_options = ['remember', 'overwrite', 'revision',
927
1043
custom_help('verbose',
928
1044
help='Show logs of pulled revisions.'),
1045
custom_help('directory',
930
1046
help='Branch to pull into, '
931
'rather than the one containing the working directory.',
1047
'rather than the one containing the working directory.'),
936
1049
help="Perform a local pull in a bound "
937
1050
"branch. Local pulls are not applied to "
938
1051
"the master branch."
1054
help="Show base revision text in conflicts.")
941
1056
takes_args = ['location?']
942
1057
encoding_type = 'replace'
944
def run(self, location=None, remember=False, overwrite=False,
1059
def run(self, location=None, remember=None, overwrite=False,
945
1060
revision=None, verbose=False,
946
directory=None, local=False):
1061
directory=None, local=False,
947
1063
# FIXME: too much stuff is in the command class
948
1064
revision_id = None
949
1065
mergeable = None
1042
1164
do a merge (see bzr help merge) from the other branch, and commit that.
1043
1165
After that you will be able to do a push without '--overwrite'.
1045
If there is no default push location set, the first push will set it.
1046
After that, you can omit the location to use the default. To change the
1047
default, use --remember. The value will only be saved if the remote
1048
location can be accessed.
1167
If there is no default push location set, the first push will set it (use
1168
--no-remember to avoid setting it). After that, you can omit the
1169
location to use the default. To change the default, use --remember. The
1170
value will only be saved if the remote location can be accessed.
1172
The --verbose option will display the revisions pushed using the log_format
1173
configuration option. You can use a different format by overriding it with
1174
-Olog_format=<other_format>.
1051
1177
_see_also = ['pull', 'update', 'working-trees']
1075
1198
Option('strict',
1076
1199
help='Refuse to push if there are uncommitted changes in'
1077
1200
' the working tree, --no-strict disables the check.'),
1202
help="Don't populate the working tree, even for protocols"
1203
" that support it."),
1079
1205
takes_args = ['location?']
1080
1206
encoding_type = 'replace'
1082
def run(self, location=None, remember=False, overwrite=False,
1208
def run(self, location=None, remember=None, overwrite=False,
1083
1209
create_prefix=False, verbose=False, revision=None,
1084
1210
use_existing_dir=False, directory=None, stacked_on=None,
1085
stacked=False, strict=None):
1211
stacked=False, strict=None, no_tree=False):
1086
1212
from bzrlib.push import _show_push_branch
1088
1214
if directory is None:
1089
1215
directory = '.'
1090
1216
# Get the source branch
1091
1217
(tree, br_from,
1092
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1218
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1096
1219
# Get the tip's revision_id
1097
1220
revision = _get_one_revision('push', revision)
1098
1221
if revision is not None:
1099
1222
revision_id = revision.in_history(br_from).rev_id
1101
1224
revision_id = None
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
tree, more='Use --no-strict to force the push.')
1225
if tree is not None and revision_id is None:
1226
tree.check_changed_or_out_of_date(
1227
strict, 'push_strict',
1228
more_error='Use --no-strict to force the push.',
1229
more_warning='Uncommitted changes will not be pushed.')
1113
1230
# Get the stacked_on branch, if any
1114
1231
if stacked_on is not None:
1115
1232
stacked_on = urlutils.normalize_url(stacked_on)
1125
1242
# error by the feedback given to them. RBC 20080227.
1126
1243
stacked_on = parent_url
1127
1244
if not stacked_on:
1128
raise errors.BzrCommandError(
1129
"Could not determine branch to refer to.")
1245
raise errors.BzrCommandError(gettext(
1246
"Could not determine branch to refer to."))
1131
1248
# Get the destination location
1132
1249
if location is None:
1133
1250
stored_loc = br_from.get_push_location()
1134
1251
if stored_loc is None:
1135
raise errors.BzrCommandError(
1136
"No push location known or specified.")
1252
raise errors.BzrCommandError(gettext(
1253
"No push location known or specified."))
1138
1255
display_url = urlutils.unescape_for_display(stored_loc,
1139
1256
self.outf.encoding)
1140
self.outf.write("Using saved push location: %s\n" % display_url)
1257
note(gettext("Using saved push location: %s") % display_url)
1141
1258
location = stored_loc
1143
1260
_show_push_branch(br_from, revision_id, location, self.outf,
1144
1261
verbose=verbose, overwrite=overwrite, remember=remember,
1145
1262
stacked_on=stacked_on, create_prefix=create_prefix,
1146
use_existing_dir=use_existing_dir)
1263
use_existing_dir=use_existing_dir, no_tree=no_tree)
1149
1266
class cmd_branch(Command):
1150
"""Create a new branch that is a copy of an existing branch.
1267
__doc__ = """Create a new branch that is a copy of an existing branch.
1152
1269
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1153
1270
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1188
1309
def run(self, from_location, to_location=None, revision=None,
1189
1310
hardlink=False, stacked=False, standalone=False, no_tree=False,
1190
use_existing_dir=False, switch=False, bind=False):
1311
use_existing_dir=False, switch=False, bind=False,
1191
1313
from bzrlib import switch as _mod_switch
1192
1314
from bzrlib.tag import _merge_tags_if_possible
1193
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1315
if self.invoked_as in ['get', 'clone']:
1316
ui.ui_factory.show_user_warning(
1317
'deprecated_command',
1318
deprecated_name=self.invoked_as,
1319
recommended_name='branch',
1320
deprecated_in_version='2.4')
1321
accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1323
if not (hardlink or files_from):
1324
# accelerator_tree is usually slower because you have to read N
1325
# files (no readahead, lots of seeks, etc), but allow the user to
1326
# explicitly request it
1327
accelerator_tree = None
1328
if files_from is not None and files_from != from_location:
1329
accelerator_tree = WorkingTree.open(files_from)
1195
1330
revision = _get_one_revision('branch', revision)
1197
self.add_cleanup(br_from.unlock)
1331
self.add_cleanup(br_from.lock_read().unlock)
1198
1332
if revision is not None:
1199
1333
revision_id = revision.as_revision_id(br_from)
1204
1338
revision_id = br_from.last_revision()
1205
1339
if to_location is None:
1206
to_location = urlutils.derive_to_location(from_location)
1340
to_location = getattr(br_from, "name", None)
1341
if to_location is None:
1342
to_location = urlutils.derive_to_location(from_location)
1207
1343
to_transport = transport.get_transport(to_location)
1209
1345
to_transport.mkdir('.')
1210
1346
except errors.FileExists:
1211
if not use_existing_dir:
1212
raise errors.BzrCommandError('Target directory "%s" '
1213
'already exists.' % to_location)
1348
to_dir = controldir.ControlDir.open_from_transport(
1350
except errors.NotBranchError:
1351
if not use_existing_dir:
1352
raise errors.BzrCommandError(gettext('Target directory "%s" '
1353
'already exists.') % to_location)
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1358
to_dir.open_branch()
1217
1359
except errors.NotBranchError:
1220
1362
raise errors.AlreadyBranchError(to_location)
1221
1363
except errors.NoSuchFile:
1222
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1364
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1225
# preserve whatever source format we have.
1226
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1227
possible_transports=[to_transport],
1228
accelerator_tree=accelerator_tree,
1229
hardlink=hardlink, stacked=stacked,
1230
force_new_repo=standalone,
1231
create_tree_if_local=not no_tree,
1232
source_branch=br_from)
1233
branch = dir.open_branch()
1234
except errors.NoSuchRevision:
1235
to_transport.delete_tree('.')
1236
msg = "The branch %s has no revision %s." % (from_location,
1238
raise errors.BzrCommandError(msg)
1370
# preserve whatever source format we have.
1371
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1372
possible_transports=[to_transport],
1373
accelerator_tree=accelerator_tree,
1374
hardlink=hardlink, stacked=stacked,
1375
force_new_repo=standalone,
1376
create_tree_if_local=not no_tree,
1377
source_branch=br_from)
1378
branch = to_dir.open_branch(
1379
possible_transports=[
1380
br_from.bzrdir.root_transport, to_transport])
1381
except errors.NoSuchRevision:
1382
to_transport.delete_tree('.')
1383
msg = gettext("The branch {0} has no revision {1}.").format(
1384
from_location, revision)
1385
raise errors.BzrCommandError(msg)
1387
branch = br_from.sprout(to_dir, revision_id=revision_id)
1239
1388
_merge_tags_if_possible(br_from, branch)
1240
1389
# If the source branch is stacked, the new branch may
1241
1390
# be stacked whether we asked for that explicitly or not.
1242
1391
# We therefore need a try/except here and not just 'if stacked:'
1244
note('Created new stacked branch referring to %s.' %
1393
note(gettext('Created new stacked branch referring to %s.') %
1245
1394
branch.get_stacked_on_url())
1246
1395
except (errors.NotStacked, errors.UnstackableBranchFormat,
1247
1396
errors.UnstackableRepositoryFormat), e:
1248
note('Branched %d revision(s).' % branch.revno())
1397
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1250
1399
# Bind to the parent
1251
1400
parent_branch = Branch.open(from_location)
1252
1401
branch.bind(parent_branch)
1253
note('New branch bound to %s' % from_location)
1402
note(gettext('New branch bound to %s') % from_location)
1255
1404
# Switch to the new branch
1256
1405
wt, _ = WorkingTree.open_containing('.')
1257
1406
_mod_switch.switch(wt.bzrdir, branch)
1258
note('Switched to branch: %s',
1407
note(gettext('Switched to branch: %s'),
1259
1408
urlutils.unescape_for_display(branch.base, 'utf-8'))
1411
class cmd_branches(Command):
1412
__doc__ = """List the branches available at the current location.
1414
This command will print the names of all the branches at the current
1418
takes_args = ['location?']
1420
Option('recursive', short_name='R',
1421
help='Recursively scan for branches rather than '
1422
'just looking in the specified location.')]
1424
def run(self, location=".", recursive=False):
1426
t = transport.get_transport(location)
1427
if not t.listable():
1428
raise errors.BzrCommandError(
1429
"Can't scan this type of location.")
1430
for b in controldir.ControlDir.find_branches(t):
1431
self.outf.write("%s\n" % urlutils.unescape_for_display(
1432
urlutils.relative_url(t.base, b.base),
1433
self.outf.encoding).rstrip("/"))
1435
dir = controldir.ControlDir.open_containing(location)[0]
1436
for branch in dir.list_branches():
1437
if branch.name is None:
1438
self.outf.write(gettext(" (default)\n"))
1440
self.outf.write(" %s\n" % branch.name.encode(
1441
self.outf.encoding))
1262
1444
class cmd_checkout(Command):
1263
"""Create a new checkout of an existing branch.
1445
__doc__ = """Create a new checkout of an existing branch.
1265
1447
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1266
1448
the branch found in '.'. This is useful if you have removed the working tree
1363
1548
class cmd_update(Command):
1364
"""Update a tree to have the latest code committed to its branch.
1366
This will perform a merge into the working tree, and may generate
1367
conflicts. If you have any local changes, you will still
1368
need to commit them after the update for the update to be complete.
1370
If you want to discard your local changes, you can just do a
1371
'bzr revert' instead of 'bzr commit' after the update.
1373
If the tree's branch is bound to a master branch, it will also update
1549
__doc__ = """Update a working tree to a new revision.
1551
This will perform a merge of the destination revision (the tip of the
1552
branch, or the specified revision) into the working tree, and then make
1553
that revision the basis revision for the working tree.
1555
You can use this to visit an older revision, or to update a working tree
1556
that is out of date from its branch.
1558
If there are any uncommitted changes in the tree, they will be carried
1559
across and remain as uncommitted changes after the update. To discard
1560
these changes, use 'bzr revert'. The uncommitted changes may conflict
1561
with the changes brought in by the change in basis revision.
1563
If the tree's branch is bound to a master branch, bzr will also update
1374
1564
the branch from the master.
1566
You cannot update just a single file or directory, because each Bazaar
1567
working tree has just a single basis revision. If you want to restore a
1568
file that has been removed locally, use 'bzr revert' instead of 'bzr
1569
update'. If you want to restore a file to its state in a previous
1570
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1571
out the old content of that file to a new location.
1573
The 'dir' argument, if given, must be the location of the root of a
1574
working tree to update. By default, the working tree that contains the
1575
current working directory is used.
1377
1578
_see_also = ['pull', 'working-trees', 'status-flags']
1378
1579
takes_args = ['dir?']
1379
takes_options = ['revision']
1580
takes_options = ['revision',
1582
help="Show base revision text in conflicts."),
1380
1584
aliases = ['up']
1382
def run(self, dir='.', revision=None):
1586
def run(self, dir=None, revision=None, show_base=None):
1383
1587
if revision is not None and len(revision) != 1:
1384
raise errors.BzrCommandError(
1385
"bzr update --revision takes exactly one revision")
1386
tree = WorkingTree.open_containing(dir)[0]
1588
raise errors.BzrCommandError(gettext(
1589
"bzr update --revision takes exactly one revision"))
1591
tree = WorkingTree.open_containing('.')[0]
1593
tree, relpath = WorkingTree.open_containing(dir)
1596
raise errors.BzrCommandError(gettext(
1597
"bzr update can only update a whole tree, "
1598
"not a file or subdirectory"))
1387
1599
branch = tree.branch
1388
1600
possible_transports = []
1389
1601
master = branch.get_master_branch(
1390
1602
possible_transports=possible_transports)
1391
1603
if master is not None:
1393
1604
branch_location = master.base
1607
branch_location = tree.branch.base
1395
1608
tree.lock_tree_write()
1396
branch_location = tree.branch.base
1397
1609
self.add_cleanup(tree.unlock)
1398
1610
# get rid of the final '/' and be ready for display
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1611
branch_location = urlutils.unescape_for_display(
1612
branch_location.rstrip('/'),
1401
1614
existing_pending_merges = tree.get_parent_ids()[1:]
1402
1615
if master is None:
1424
1637
change_reporter,
1425
1638
possible_transports=possible_transports,
1426
1639
revision=revision_id,
1641
show_base=show_base)
1428
1642
except errors.NoSuchRevision, e:
1429
raise errors.BzrCommandError(
1643
raise errors.BzrCommandError(gettext(
1430
1644
"branch has no revision %s\n"
1431
1645
"bzr update --revision only works"
1432
" for a revision in the branch history"
1646
" for a revision in the branch history")
1433
1647
% (e.revision))
1434
revno = tree.branch.revision_id_to_revno(
1648
revno = tree.branch.revision_id_to_dotted_revno(
1435
1649
_mod_revision.ensure_null(tree.last_revision()))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
if tree.get_parent_ids()[1:] != existing_pending_merges:
1439
note('Your local commits will now show as pending merges with '
1440
"'bzr status', and can be committed with 'bzr commit'.")
1650
note(gettext('Updated to revision {0} of branch {1}').format(
1651
'.'.join(map(str, revno)), branch_location))
1652
parent_ids = tree.get_parent_ids()
1653
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1654
note(gettext('Your local commits will now show as pending merges with '
1655
"'bzr status', and can be committed with 'bzr commit'."))
1441
1656
if conflicts != 0:
1485
1700
noise_level = 0
1486
1701
from bzrlib.info import show_bzrdir_info
1487
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
1702
show_bzrdir_info(controldir.ControlDir.open_containing(location)[0],
1488
1703
verbose=noise_level, outfile=self.outf)
1491
1706
class cmd_remove(Command):
1492
"""Remove files or directories.
1707
__doc__ = """Remove files or directories.
1494
This makes bzr stop tracking changes to the specified files. bzr will delete
1495
them if they can easily be recovered using revert. If no options or
1496
parameters are given bzr will scan for files that are being tracked by bzr
1497
but missing in your tree and stop tracking them for you.
1709
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1710
delete them if they can easily be recovered using revert otherwise they
1711
will be backed up (adding an extention of the form .~#~). If no options or
1712
parameters are given Bazaar will scan for files that are being tracked by
1713
Bazaar but missing in your tree and stop tracking them for you.
1499
1715
takes_args = ['file*']
1500
1716
takes_options = ['verbose',
1502
1718
RegistryOption.from_kwargs('file-deletion-strategy',
1503
1719
'The file deletion mode to be used.',
1504
1720
title='Deletion Strategy', value_switches=True, enum_switch=False,
1505
safe='Only delete files if they can be'
1506
' safely recovered (default).',
1721
safe='Backup changed files (default).',
1507
1722
keep='Delete from bzr but leave the working copy.',
1723
no_backup='Don\'t backup changed files.',
1508
1724
force='Delete all the specified files, even if they can not be '
1509
'recovered and even if they are non-empty directories.')]
1725
'recovered and even if they are non-empty directories. '
1726
'(deprecated, use no-backup)')]
1510
1727
aliases = ['rm', 'del']
1511
1728
encoding_type = 'replace'
1513
1730
def run(self, file_list, verbose=False, new=False,
1514
1731
file_deletion_strategy='safe'):
1515
tree, file_list = tree_files(file_list)
1732
if file_deletion_strategy == 'force':
1733
note(gettext("(The --force option is deprecated, rather use --no-backup "
1735
file_deletion_strategy = 'no-backup'
1737
tree, file_list = WorkingTree.open_containing_paths(file_list)
1517
1739
if file_list is not None:
1518
1740
file_list = [f for f in file_list]
1521
self.add_cleanup(tree.unlock)
1742
self.add_cleanup(tree.lock_write().unlock)
1522
1743
# Heuristics should probably all move into tree.remove_smart or
1714
1951
to_transport.ensure_base()
1715
1952
except errors.NoSuchFile:
1716
1953
if not create_prefix:
1717
raise errors.BzrCommandError("Parent directory of %s"
1954
raise errors.BzrCommandError(gettext("Parent directory of %s"
1718
1955
" does not exist."
1719
1956
"\nYou may supply --create-prefix to create all"
1720
" leading parent directories."
1957
" leading parent directories.")
1722
1959
to_transport.create_prefix()
1725
a_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1962
a_bzrdir = controldir.ControlDir.open_from_transport(to_transport)
1726
1963
except errors.NotBranchError:
1727
1964
# really a NotBzrDir error...
1728
create_branch = bzrdir.BzrDir.create_branch_convenience
1965
create_branch = controldir.ControlDir.create_branch_convenience
1967
force_new_tree = False
1969
force_new_tree = None
1729
1970
branch = create_branch(to_transport.base, format=format,
1730
possible_transports=[to_transport])
1971
possible_transports=[to_transport],
1972
force_new_tree=force_new_tree)
1731
1973
a_bzrdir = branch.bzrdir
1733
1975
from bzrlib.transport.local import LocalTransport
1936
2202
elif ':' in prefix:
1937
2203
old_label, new_label = prefix.split(":")
1939
raise errors.BzrCommandError(
2205
raise errors.BzrCommandError(gettext(
1940
2206
'--prefix expects two values separated by a colon'
1941
' (eg "old/:new/")')
2207
' (eg "old/:new/")'))
1943
2209
if revision and len(revision) > 2:
1944
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1945
' one or two revision specifiers')
2210
raise errors.BzrCommandError(gettext('bzr diff --revision takes exactly'
2211
' one or two revision specifiers'))
2213
if using is not None and format is not None:
2214
raise errors.BzrCommandError(gettext(
2215
'{0} and {1} are mutually exclusive').format(
2216
'--using', '--format'))
1947
2218
(old_tree, new_tree,
1948
2219
old_branch, new_branch,
1949
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1950
file_list, revision, old, new, apply_view=True)
2220
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2221
file_list, revision, old, new, self.add_cleanup, apply_view=True)
2222
# GNU diff on Windows uses ANSI encoding for filenames
2223
path_encoding = osutils.get_diff_header_encoding()
1951
2224
return show_diff_trees(old_tree, new_tree, sys.stdout,
1952
2225
specific_files=specific_files,
1953
2226
external_diff_options=diff_options,
1954
2227
old_label=old_label, new_label=new_label,
1955
extra_trees=extra_trees, using=using)
2228
extra_trees=extra_trees,
2229
path_encoding=path_encoding,
1958
2234
class cmd_deleted(Command):
1959
"""List files deleted in the working tree.
2235
__doc__ = """List files deleted in the working tree.
1961
2237
# TODO: Show files deleted since a previous revision, or
1962
2238
# between two revisions.
1987
2261
class cmd_modified(Command):
1988
"""List files modified in working tree.
2262
__doc__ = """List files modified in working tree.
1992
2266
_see_also = ['status', 'ls']
1995
help='Write an ascii NUL (\\0) separator '
1996
'between files rather than a newline.')
2267
takes_options = ['directory', 'null']
1999
2269
@display_command
2000
def run(self, null=False):
2001
tree = WorkingTree.open_containing(u'.')[0]
2270
def run(self, null=False, directory=u'.'):
2271
tree = WorkingTree.open_containing(directory)[0]
2272
self.add_cleanup(tree.lock_read().unlock)
2002
2273
td = tree.changes_from(tree.basis_tree())
2003
2275
for path, id, kind, text_modified, meta_modified in td.modified:
2005
2277
self.outf.write(path + '\0')
2010
2282
class cmd_added(Command):
2011
"""List files added in working tree.
2283
__doc__ = """List files added in working tree.
2015
2287
_see_also = ['status', 'ls']
2018
help='Write an ascii NUL (\\0) separator '
2019
'between files rather than a newline.')
2288
takes_options = ['directory', 'null']
2022
2290
@display_command
2023
def run(self, null=False):
2024
wt = WorkingTree.open_containing(u'.')[0]
2026
self.add_cleanup(wt.unlock)
2291
def run(self, null=False, directory=u'.'):
2292
wt = WorkingTree.open_containing(directory)[0]
2293
self.add_cleanup(wt.lock_read().unlock)
2027
2294
basis = wt.basis_tree()
2029
self.add_cleanup(basis.unlock)
2295
self.add_cleanup(basis.lock_read().unlock)
2030
2296
basis_inv = basis.inventory
2031
2297
inv = wt.inventory
2032
2298
for file_id in inv:
2033
if file_id in basis_inv:
2299
if basis_inv.has_id(file_id):
2035
2301
if inv.is_root(file_id) and len(basis_inv) == 0:
2037
2303
path = inv.id2path(file_id)
2038
if not os.access(osutils.abspath(path), os.F_OK):
2304
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2041
2307
self.outf.write(path + '\0')
2259
2533
Option('show-diff',
2260
2534
short_name='p',
2261
2535
help='Show changes made in each revision as a patch.'),
2262
Option('include-merges',
2536
Option('include-merged',
2263
2537
help='Show merged revisions like --levels 0 does.'),
2538
Option('include-merges', hidden=True,
2539
help='Historical alias for --include-merged.'),
2540
Option('omit-merges',
2541
help='Do not report commits with more than one parent.'),
2542
Option('exclude-common-ancestry',
2543
help='Display only the revisions that are not part'
2544
' of both ancestries (require -rX..Y).'
2546
Option('signatures',
2547
help='Show digital signature validity.'),
2550
help='Show revisions whose properties match this '
2553
ListOption('match-message',
2554
help='Show revisions whose message matches this '
2557
ListOption('match-committer',
2558
help='Show revisions whose committer matches this '
2561
ListOption('match-author',
2562
help='Show revisions whose authors match this '
2565
ListOption('match-bugs',
2566
help='Show revisions whose bugs match this '
2265
2570
encoding_type = 'replace'
2278
2583
show_diff=False,
2279
include_merges=False):
2584
include_merged=None,
2586
exclude_common_ancestry=False,
2590
match_committer=None,
2594
include_merges=symbol_versioning.DEPRECATED_PARAMETER,
2280
2596
from bzrlib.log import (
2282
2598
make_log_request_dict,
2283
2599
_get_info_for_log_files,
2285
2601
direction = (forward and 'forward') or 'reverse'
2602
if symbol_versioning.deprecated_passed(include_merges):
2603
ui.ui_factory.show_user_warning(
2604
'deprecated_command_option',
2605
deprecated_name='--include-merges',
2606
recommended_name='--include-merged',
2607
deprecated_in_version='2.5',
2608
command=self.invoked_as)
2609
if include_merged is None:
2610
include_merged = include_merges
2612
raise errors.BzrCommandError(gettext(
2613
'{0} and {1} are mutually exclusive').format(
2614
'--include-merges', '--include-merged'))
2615
if include_merged is None:
2616
include_merged = False
2617
if (exclude_common_ancestry
2618
and (revision is None or len(revision) != 2)):
2619
raise errors.BzrCommandError(gettext(
2620
'--exclude-common-ancestry requires -r with two revisions'))
2287
2622
if levels is None:
2290
raise errors.BzrCommandError(
2291
'--levels and --include-merges are mutually exclusive')
2625
raise errors.BzrCommandError(gettext(
2626
'{0} and {1} are mutually exclusive').format(
2627
'--levels', '--include-merged'))
2293
2629
if change is not None:
2294
2630
if len(change) > 1:
2295
2631
raise errors.RangeInChangeOption()
2296
2632
if revision is not None:
2297
raise errors.BzrCommandError(
2298
'--revision and --change are mutually exclusive')
2633
raise errors.BzrCommandError(gettext(
2634
'{0} and {1} are mutually exclusive').format(
2635
'--revision', '--change'))
2300
2637
revision = change
2474
2835
help='Recurse into subdirectories.'),
2475
2836
Option('from-root',
2476
2837
help='Print paths relative to the root of the branch.'),
2477
Option('unknown', help='Print unknown files.'),
2838
Option('unknown', short_name='u',
2839
help='Print unknown files.'),
2478
2840
Option('versioned', help='Print versioned files.',
2479
2841
short_name='V'),
2480
Option('ignored', help='Print ignored files.'),
2482
help='Write an ascii NUL (\\0) separator '
2483
'between files rather than a newline.'),
2842
Option('ignored', short_name='i',
2843
help='Print ignored files.'),
2844
Option('kind', short_name='k',
2485
2845
help='List entries of a particular kind: file, directory, symlink.',
2489
2851
@display_command
2490
2852
def run(self, revision=None, verbose=False,
2491
2853
recursive=False, from_root=False,
2492
2854
unknown=False, versioned=False, ignored=False,
2493
null=False, kind=None, show_ids=False, path=None):
2855
null=False, kind=None, show_ids=False, path=None, directory=None):
2495
2857
if kind and kind not in ('file', 'directory', 'symlink'):
2496
raise errors.BzrCommandError('invalid kind specified')
2858
raise errors.BzrCommandError(gettext('invalid kind specified'))
2498
2860
if verbose and null:
2499
raise errors.BzrCommandError('Cannot set both --verbose and --null')
2861
raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
2500
2862
all = not (unknown or versioned or ignored)
2502
2864
selection = {'I':ignored, '?':unknown, 'V':versioned}
2653
3030
_see_also = ['status', 'ignored', 'patterns']
2654
3031
takes_args = ['name_pattern*']
2656
Option('old-default-rules',
2657
help='Write out the ignore rules bzr < 0.9 always used.')
3032
takes_options = ['directory',
3033
Option('default-rules',
3034
help='Display the default ignore rules that bzr uses.')
2660
def run(self, name_pattern_list=None, old_default_rules=None):
3037
def run(self, name_pattern_list=None, default_rules=None,
2661
3039
from bzrlib import ignores
2662
if old_default_rules is not None:
2663
# dump the rules and exit
2664
for pattern in ignores.OLD_DEFAULTS:
3040
if default_rules is not None:
3041
# dump the default rules and exit
3042
for pattern in ignores.USER_DEFAULTS:
3043
self.outf.write("%s\n" % pattern)
2667
3045
if not name_pattern_list:
2668
raise errors.BzrCommandError("ignore requires at least one "
2669
"NAME_PATTERN or --old-default-rules")
3046
raise errors.BzrCommandError(gettext("ignore requires at least one "
3047
"NAME_PATTERN or --default-rules."))
2670
3048
name_pattern_list = [globbing.normalize_pattern(p)
2671
3049
for p in name_pattern_list]
3051
bad_patterns_count = 0
3052
for p in name_pattern_list:
3053
if not globbing.Globster.is_pattern_valid(p):
3054
bad_patterns_count += 1
3055
bad_patterns += ('\n %s' % p)
3057
msg = (ngettext('Invalid ignore pattern found. %s',
3058
'Invalid ignore patterns found. %s',
3059
bad_patterns_count) % bad_patterns)
3060
ui.ui_factory.show_error(msg)
3061
raise errors.InvalidPattern('')
2672
3062
for name_pattern in name_pattern_list:
2673
3063
if (name_pattern[0] == '/' or
2674
3064
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2675
raise errors.BzrCommandError(
2676
"NAME_PATTERN should not be an absolute path")
2677
tree, relpath = WorkingTree.open_containing(u'.')
3065
raise errors.BzrCommandError(gettext(
3066
"NAME_PATTERN should not be an absolute path"))
3067
tree, relpath = WorkingTree.open_containing(directory)
2678
3068
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2679
3069
ignored = globbing.Globster(name_pattern_list)
3071
self.add_cleanup(tree.lock_read().unlock)
2682
3072
for entry in tree.list_files():
2684
3074
if id is not None:
2685
3075
filename = entry[0]
2686
3076
if ignored.match(filename):
2687
matches.append(filename.encode('utf-8'))
3077
matches.append(filename)
2689
3078
if len(matches) > 0:
2690
print "Warning: the following files are version controlled and" \
2691
" match your ignore pattern:\n%s" \
2692
"\nThese files will continue to be version controlled" \
2693
" unless you 'bzr remove' them." % ("\n".join(matches),)
3079
self.outf.write(gettext("Warning: the following files are version "
3080
"controlled and match your ignore pattern:\n%s"
3081
"\nThese files will continue to be version controlled"
3082
" unless you 'bzr remove' them.\n") % ("\n".join(matches),))
2696
3085
class cmd_ignored(Command):
2697
"""List ignored files and the patterns that matched them.
3086
__doc__ = """List ignored files and the patterns that matched them.
2699
3088
List all the ignored files and the ignore pattern that caused the file to
2780
3172
help="Name of the root directory inside the exported file."),
3173
Option('per-file-timestamps',
3174
help='Set modification time of files to that of the last '
3175
'revision in which it was changed.'),
3176
Option('uncommitted',
3177
help='Export the working tree contents rather than that of the '
2782
3180
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2783
root=None, filters=False):
3181
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2784
3183
from bzrlib.export import export
2786
3185
if branch_or_subdir is None:
2787
tree = WorkingTree.open_containing(u'.')[0]
3186
branch_or_subdir = directory
3188
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3190
if tree is not None:
3191
self.add_cleanup(tree.lock_read().unlock)
3195
raise errors.BzrCommandError(
3196
gettext("--uncommitted requires a working tree"))
2791
b, subdir = Branch.open_containing(branch_or_subdir)
2794
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3199
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2796
export(rev_tree, dest, format, root, subdir, filtered=filters)
3201
export(export_tree, dest, format, root, subdir, filtered=filters,
3202
per_file_timestamps=per_file_timestamps)
2797
3203
except errors.NoSuchExportFormat, e:
2798
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3204
raise errors.BzrCommandError(
3205
gettext('Unsupported export format: %s') % e.format)
2801
3208
class cmd_cat(Command):
2802
"""Write the contents of a file as of a given revision to standard output.
3209
__doc__ = """Write the contents of a file as of a given revision to standard output.
2804
3211
If no revision is nominated, the last revision is used.
2820
3227
@display_command
2821
3228
def run(self, filename, revision=None, name_from_revision=False,
3229
filters=False, directory=None):
2823
3230
if revision is not None and len(revision) != 1:
2824
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2825
" one revision specifier")
3231
raise errors.BzrCommandError(gettext("bzr cat --revision takes exactly"
3232
" one revision specifier"))
2826
3233
tree, branch, relpath = \
2827
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2829
self.add_cleanup(branch.unlock)
3234
_open_directory_or_containing_tree_or_branch(filename, directory)
3235
self.add_cleanup(branch.lock_read().unlock)
2830
3236
return self._run(tree, branch, relpath, filename, revision,
2831
3237
name_from_revision, filters)
2835
3241
if tree is None:
2836
3242
tree = b.basis_tree()
2837
3243
rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2838
rev_tree.lock_read()
2839
self.add_cleanup(rev_tree.unlock)
3244
self.add_cleanup(rev_tree.lock_read().unlock)
2841
3246
old_file_id = rev_tree.path2id(relpath)
3248
# TODO: Split out this code to something that generically finds the
3249
# best id for a path across one or more trees; it's like
3250
# find_ids_across_trees but restricted to find just one. -- mbp
2843
3252
if name_from_revision:
2844
3253
# Try in revision if requested
2845
3254
if old_file_id is None:
2846
raise errors.BzrCommandError(
2847
"%r is not present in revision %s" % (
3255
raise errors.BzrCommandError(gettext(
3256
"{0!r} is not present in revision {1}").format(
2848
3257
filename, rev_tree.get_revision_id()))
2850
content = rev_tree.get_file_text(old_file_id)
3259
actual_file_id = old_file_id
2852
3261
cur_file_id = tree.path2id(relpath)
2854
if cur_file_id is not None:
2855
# Then try with the actual file id
2857
content = rev_tree.get_file_text(cur_file_id)
2859
except errors.NoSuchId:
2860
# The actual file id didn't exist at that time
2862
if not found and old_file_id is not None:
2863
# Finally try with the old file id
2864
content = rev_tree.get_file_text(old_file_id)
2867
# Can't be found anywhere
2868
raise errors.BzrCommandError(
2869
"%r is not present in revision %s" % (
3262
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3263
actual_file_id = cur_file_id
3264
elif old_file_id is not None:
3265
actual_file_id = old_file_id
3267
raise errors.BzrCommandError(gettext(
3268
"{0!r} is not present in revision {1}").format(
2870
3269
filename, rev_tree.get_revision_id()))
2872
from bzrlib.filters import (
2873
ContentFilterContext,
2874
filtered_output_bytes,
2876
filters = rev_tree._content_filter_stack(relpath)
2877
chunks = content.splitlines(True)
2878
content = filtered_output_bytes(chunks, filters,
2879
ContentFilterContext(relpath, rev_tree))
2881
self.outf.writelines(content)
3271
from bzrlib.filter_tree import ContentFilterTree
3272
filter_tree = ContentFilterTree(rev_tree,
3273
rev_tree._content_filter_stack)
3274
content = filter_tree.get_file_text(actual_file_id)
2884
self.outf.write(content)
3276
content = rev_tree.get_file_text(actual_file_id)
3278
self.outf.write(content)
2887
3281
class cmd_local_time_offset(Command):
2888
"""Show the offset in seconds from GMT to local time."""
3282
__doc__ = """Show the offset in seconds from GMT to local time."""
2890
3284
@display_command
2892
print osutils.local_time_offset()
3286
self.outf.write("%s\n" % osutils.local_time_offset())
2896
3290
class cmd_commit(Command):
2897
"""Commit changes into a new revision.
3291
__doc__ = """Commit changes into a new revision.
2899
3293
An explanatory message needs to be given for each commit. This is
2900
3294
often done by using the --message option (getting the message from the
2948
3342
to trigger updates to external systems like bug trackers. The --fixes
2949
3343
option can be used to record the association between a revision and
2950
3344
one or more bugs. See ``bzr help bugs`` for details.
2952
A selective commit may fail in some cases where the committed
2953
tree would be invalid. Consider::
2958
bzr commit foo -m "committing foo"
2959
bzr mv foo/bar foo/baz
2962
bzr commit foo/bar -m "committing bar but not baz"
2964
In the example above, the last commit will fail by design. This gives
2965
the user the opportunity to decide whether they want to commit the
2966
rename at the same time, separately first, or not at all. (As a general
2967
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2969
# TODO: Run hooks on tree to-be-committed, and after commit.
2971
# TODO: Strict commit that fails if there are deleted files.
2972
# (what does "deleted files" mean ??)
2974
# TODO: Give better message for -s, --summary, used by tla people
2976
# XXX: verbose currently does nothing
2978
3347
_see_also = ['add', 'bugs', 'hooks', 'uncommit']
2979
3348
takes_args = ['selected*']
3008
3377
"the master branch until a normal commit "
3009
3378
"is performed."
3380
Option('show-diff', short_name='p',
3012
3381
help='When no message is supplied, show the diff along'
3013
3382
' with the status summary in the message editor.'),
3384
help='When committing to a foreign version control '
3385
'system do not push data that can not be natively '
3015
3388
aliases = ['ci', 'checkin']
3017
3390
def _iter_bug_fix_urls(self, fixes, branch):
3391
default_bugtracker = None
3018
3392
# Configure the properties for bug fixing attributes.
3019
3393
for fixed_bug in fixes:
3020
3394
tokens = fixed_bug.split(':')
3021
if len(tokens) != 2:
3022
raise errors.BzrCommandError(
3395
if len(tokens) == 1:
3396
if default_bugtracker is None:
3397
branch_config = branch.get_config()
3398
default_bugtracker = branch_config.get_user_option(
3400
if default_bugtracker is None:
3401
raise errors.BzrCommandError(gettext(
3402
"No tracker specified for bug %s. Use the form "
3403
"'tracker:id' or specify a default bug tracker "
3404
"using the `bugtracker` option.\nSee "
3405
"\"bzr help bugs\" for more information on this "
3406
"feature. Commit refused.") % fixed_bug)
3407
tag = default_bugtracker
3409
elif len(tokens) != 2:
3410
raise errors.BzrCommandError(gettext(
3023
3411
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3024
3412
"See \"bzr help bugs\" for more information on this "
3025
"feature.\nCommit refused." % fixed_bug)
3026
tag, bug_id = tokens
3413
"feature.\nCommit refused.") % fixed_bug)
3415
tag, bug_id = tokens
3028
3417
yield bugtracker.get_bug_url(tag, branch, bug_id)
3029
3418
except errors.UnknownBugTrackerAbbreviation:
3030
raise errors.BzrCommandError(
3031
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3419
raise errors.BzrCommandError(gettext(
3420
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3032
3421
except errors.MalformedBugIdentifier, e:
3033
raise errors.BzrCommandError(
3034
"%s\nCommit refused." % (str(e),))
3422
raise errors.BzrCommandError(gettext(
3423
"%s\nCommit refused.") % (str(e),))
3036
3425
def run(self, message=None, file=None, verbose=False, selected_list=None,
3037
3426
unchanged=False, strict=False, local=False, fixes=None,
3038
author=None, show_diff=False, exclude=None, commit_time=None):
3427
author=None, show_diff=False, exclude=None, commit_time=None,
3039
3429
from bzrlib.errors import (
3040
3430
PointlessCommit,
3041
3431
ConflictsInTree,
3094
3479
'(use --file "%(f)s" to take commit message from that file)'
3095
3480
% { 'f': message })
3096
3481
ui.ui_factory.show_warning(warning_msg)
3483
message = message.replace('\r\n', '\n')
3484
message = message.replace('\r', '\n')
3486
raise errors.BzrCommandError(gettext(
3487
"please specify either --message or --file"))
3098
3489
def get_message(commit_obj):
3099
3490
"""Callback to get commit message"""
3100
my_message = message
3101
if my_message is not None and '\r' in my_message:
3102
my_message = my_message.replace('\r\n', '\n')
3103
my_message = my_message.replace('\r', '\n')
3104
if my_message is None and not file:
3105
t = make_commit_message_template_encoded(tree,
3494
my_message = f.read().decode(osutils.get_user_encoding())
3497
elif message is not None:
3498
my_message = message
3500
# No message supplied: make one up.
3501
# text is the status of the tree
3502
text = make_commit_message_template_encoded(tree,
3106
3503
selected_list, diff=show_diff,
3107
3504
output_encoding=osutils.get_user_encoding())
3108
start_message = generate_commit_message_template(commit_obj)
3109
my_message = edit_commit_message_encoded(t,
3110
start_message=start_message)
3111
if my_message is None:
3112
raise errors.BzrCommandError("please specify a commit"
3113
" message with either --message or --file")
3114
elif my_message and file:
3115
raise errors.BzrCommandError(
3116
"please specify either --message or --file")
3118
my_message = codecs.open(file, 'rt',
3119
osutils.get_user_encoding()).read()
3120
if my_message == "":
3121
raise errors.BzrCommandError("empty commit message specified")
3505
# start_message is the template generated from hooks
3506
# XXX: Warning - looks like hooks return unicode,
3507
# make_commit_message_template_encoded returns user encoding.
3508
# We probably want to be using edit_commit_message instead to
3510
my_message = set_commit_message(commit_obj)
3511
if my_message is None:
3512
start_message = generate_commit_message_template(commit_obj)
3513
my_message = edit_commit_message_encoded(text,
3514
start_message=start_message)
3515
if my_message is None:
3516
raise errors.BzrCommandError(gettext("please specify a commit"
3517
" message with either --message or --file"))
3518
if my_message == "":
3519
raise errors.BzrCommandError(gettext("Empty commit message specified."
3520
" Please specify a commit message with either"
3521
" --message or --file or leave a blank message"
3522
" with --message \"\"."))
3122
3523
return my_message
3124
3525
# The API permits a commit with a filter of [] to mean 'select nothing'
3132
3533
reporter=None, verbose=verbose, revprops=properties,
3133
3534
authors=author, timestamp=commit_stamp,
3134
3535
timezone=offset,
3135
exclude=safe_relpath_files(tree, exclude))
3536
exclude=tree.safe_relpath_files(exclude),
3136
3538
except PointlessCommit:
3137
# FIXME: This should really happen before the file is read in;
3138
# perhaps prepare the commit; get the message; then actually commit
3139
raise errors.BzrCommandError("No changes to commit."
3140
" Use --unchanged to commit anyhow.")
3539
raise errors.BzrCommandError(gettext("No changes to commit."
3540
" Please 'bzr add' the files you want to commit, or use"
3541
" --unchanged to force an empty commit."))
3141
3542
except ConflictsInTree:
3142
raise errors.BzrCommandError('Conflicts detected in working '
3543
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3143
3544
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3145
3546
except StrictCommitFailed:
3146
raise errors.BzrCommandError("Commit refused because there are"
3147
" unknown files in the working tree.")
3547
raise errors.BzrCommandError(gettext("Commit refused because there are"
3548
" unknown files in the working tree."))
3148
3549
except errors.BoundBranchOutOfDate, e:
3149
raise errors.BzrCommandError(str(e) + "\n"
3150
'To commit to master branch, run update and then commit.\n'
3151
'You can also pass --local to commit to continue working '
3550
e.extra_help = (gettext("\n"
3551
'To commit to master branch, run update and then commit.\n'
3552
'You can also pass --local to commit to continue working '
3155
3557
class cmd_check(Command):
3156
"""Validate working tree structure, branch consistency and repository history.
3558
__doc__ = """Validate working tree structure, branch consistency and repository history.
3158
3560
This command checks various invariants about branch and repository storage
3159
3561
to detect data corruption or bzr bugs.
3225
3627
class cmd_upgrade(Command):
3226
"""Upgrade branch storage to current format.
3228
The check command or bzr developers may sometimes advise you to run
3229
this command. When the default format has changed you may also be warned
3230
during other operations to upgrade.
3628
__doc__ = """Upgrade a repository, branch or working tree to a newer format.
3630
When the default format has changed after a major new release of
3631
Bazaar, you may be informed during certain operations that you
3632
should upgrade. Upgrading to a newer format may improve performance
3633
or make new features available. It may however limit interoperability
3634
with older repositories or with older versions of Bazaar.
3636
If you wish to upgrade to a particular format rather than the
3637
current default, that can be specified using the --format option.
3638
As a consequence, you can use the upgrade command this way to
3639
"downgrade" to an earlier format, though some conversions are
3640
a one way process (e.g. changing from the 1.x default to the
3641
2.x default) so downgrading is not always possible.
3643
A backup.bzr.~#~ directory is created at the start of the conversion
3644
process (where # is a number). By default, this is left there on
3645
completion. If the conversion fails, delete the new .bzr directory
3646
and rename this one back in its place. Use the --clean option to ask
3647
for the backup.bzr directory to be removed on successful conversion.
3648
Alternatively, you can delete it by hand if everything looks good
3651
If the location given is a shared repository, dependent branches
3652
are also converted provided the repository converts successfully.
3653
If the conversion of a branch fails, remaining branches are still
3656
For more information on upgrades, see the Bazaar Upgrade Guide,
3657
http://doc.bazaar.canonical.com/latest/en/upgrade-guide/.
3233
_see_also = ['check']
3660
_see_also = ['check', 'reconcile', 'formats']
3234
3661
takes_args = ['url?']
3235
3662
takes_options = [
3236
RegistryOption('format',
3237
help='Upgrade to a specific format. See "bzr help'
3238
' formats" for details.',
3239
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
3240
converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
3241
value_switches=True, title='Branch format'),
3663
RegistryOption('format',
3664
help='Upgrade to a specific format. See "bzr help'
3665
' formats" for details.',
3666
lazy_registry=('bzrlib.controldir', 'format_registry'),
3667
converter=lambda name: controldir.format_registry.make_bzrdir(name),
3668
value_switches=True, title='Branch format'),
3670
help='Remove the backup.bzr directory if successful.'),
3672
help="Show what would be done, but don't actually do anything."),
3244
def run(self, url='.', format=None):
3675
def run(self, url='.', format=None, clean=False, dry_run=False):
3245
3676
from bzrlib.upgrade import upgrade
3246
upgrade(url, format)
3677
exceptions = upgrade(url, format, clean_up=clean, dry_run=dry_run)
3679
if len(exceptions) == 1:
3680
# Compatibility with historical behavior
3249
3686
class cmd_whoami(Command):
3250
"""Show or set bzr user id.
3687
__doc__ = """Show or set bzr user id.
3253
3690
Show the email of the current user::
3268
3706
encoding_type = 'replace'
3270
3708
@display_command
3271
def run(self, email=False, branch=False, name=None):
3709
def run(self, email=False, branch=False, name=None, directory=None):
3272
3710
if name is None:
3273
# use branch if we're inside one; otherwise global config
3275
c = Branch.open_containing('.')[0].get_config()
3276
except errors.NotBranchError:
3277
c = config.GlobalConfig()
3711
if directory is None:
3712
# use branch if we're inside one; otherwise global config
3714
c = Branch.open_containing(u'.')[0].get_config_stack()
3715
except errors.NotBranchError:
3716
c = _mod_config.GlobalStack()
3718
c = Branch.open(directory).get_config_stack()
3719
identity = c.get('email')
3279
self.outf.write(c.user_email() + '\n')
3721
self.outf.write(_mod_config.extract_email_address(identity)
3281
self.outf.write(c.username() + '\n')
3724
self.outf.write(identity + '\n')
3728
raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3284
3731
# display a warning if an email address isn't included in the given name.
3286
config.extract_email_address(name)
3733
_mod_config.extract_email_address(name)
3287
3734
except errors.NoEmailInUsername, e:
3288
3735
warning('"%s" does not seem to contain an email address. '
3289
3736
'This is allowed, but not recommended.', name)
3291
3738
# use global config unless --branch given
3293
c = Branch.open_containing('.')[0].get_config()
3740
if directory is None:
3741
c = Branch.open_containing(u'.')[0].get_config_stack()
3743
c = Branch.open(directory).get_config_stack()
3295
c = config.GlobalConfig()
3296
c.set_user_option('email', name)
3745
c = _mod_config.GlobalStack()
3746
c.set('email', name)
3299
3749
class cmd_nick(Command):
3300
"""Print or set the branch nickname.
3750
__doc__ = """Print or set the branch nickname.
3302
3752
If unset, the tree root directory name is used as the nickname.
3303
3753
To print the current nickname, execute with no argument.
3514
3969
def run(self, testspecs_list=None, verbose=False, one=False,
3515
3970
transport=None, benchmark=None,
3516
lsprof_timed=None, cache_dir=None,
3517
3972
first=False, list_only=False,
3518
3973
randomize=None, exclude=None, strict=False,
3519
3974
load_list=None, debugflag=None, starting_with=None, subunit=False,
3520
parallel=None, lsprof_tests=False):
3521
from bzrlib.tests import selftest
3522
import bzrlib.benchmarks as benchmarks
3523
from bzrlib.benchmarks import tree_creator
3525
# Make deprecation warnings visible, unless -Werror is set
3526
symbol_versioning.activate_deprecation_warnings(override=False)
3528
if cache_dir is not None:
3529
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3975
parallel=None, lsprof_tests=False,
3977
from bzrlib import tests
3530
3979
if testspecs_list is not None:
3531
3980
pattern = '|'.join(testspecs_list)
3536
3985
from bzrlib.tests import SubUnitBzrRunner
3537
3986
except ImportError:
3538
raise errors.BzrCommandError("subunit not available. subunit "
3539
"needs to be installed to use --subunit.")
3987
raise errors.BzrCommandError(gettext("subunit not available. subunit "
3988
"needs to be installed to use --subunit."))
3540
3989
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3990
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3991
# stdout, which would corrupt the subunit stream.
3992
# FIXME: This has been fixed in subunit trunk (>0.0.5) so the
3993
# following code can be deleted when it's sufficiently deployed
3994
# -- vila/mgz 20100514
3995
if (sys.platform == "win32"
3996
and getattr(sys.stdout, 'fileno', None) is not None):
3998
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3542
4000
self.additional_selftest_args.setdefault(
3543
4001
'suite_decorators', []).append(parallel)
3545
test_suite_factory = benchmarks.test_suite
3546
# Unless user explicitly asks for quiet, be verbose in benchmarks
3547
verbose = not is_quiet()
3548
# TODO: should possibly lock the history file...
3549
benchfile = open(".perf_history", "at", buffering=1)
3550
self.add_cleanup(benchfile.close)
4003
raise errors.BzrCommandError(gettext(
4004
"--benchmark is no longer supported from bzr 2.2; "
4005
"use bzr-usertest instead"))
4006
test_suite_factory = None
4008
exclude_pattern = None
3552
test_suite_factory = None
4010
exclude_pattern = '(' + '|'.join(exclude) + ')'
4012
self._disable_fsync()
3554
4013
selftest_kwargs = {"verbose": verbose,
3555
4014
"pattern": pattern,
3556
4015
"stop_on_failure": one,
3558
4017
"test_suite_factory": test_suite_factory,
3559
4018
"lsprof_timed": lsprof_timed,
3560
4019
"lsprof_tests": lsprof_tests,
3561
"bench_history": benchfile,
3562
4020
"matching_tests_first": first,
3563
4021
"list_only": list_only,
3564
4022
"random_seed": randomize,
3565
"exclude_pattern": exclude,
4023
"exclude_pattern": exclude_pattern,
3566
4024
"strict": strict,
3567
4025
"load_list": load_list,
3568
4026
"debug_flags": debugflag,
3569
4027
"starting_with": starting_with
3571
4029
selftest_kwargs.update(self.additional_selftest_args)
3572
result = selftest(**selftest_kwargs)
4031
# Make deprecation warnings visible, unless -Werror is set
4032
cleanup = symbol_versioning.activate_deprecation_warnings(
4035
result = tests.selftest(**selftest_kwargs)
3573
4038
return int(not result)
4040
def _disable_fsync(self):
4041
"""Change the 'os' functionality to not synchronize."""
4042
self._orig_fsync = getattr(os, 'fsync', None)
4043
if self._orig_fsync is not None:
4044
os.fsync = lambda filedes: None
4045
self._orig_fdatasync = getattr(os, 'fdatasync', None)
4046
if self._orig_fdatasync is not None:
4047
os.fdatasync = lambda filedes: None
3576
4050
class cmd_version(Command):
3577
"""Show version of bzr."""
4051
__doc__ = """Show version of bzr."""
3579
4053
encoding_type = 'replace'
3580
4054
takes_options = [
3614
4088
branch1 = Branch.open_containing(branch)[0]
3615
4089
branch2 = Branch.open_containing(other)[0]
3617
self.add_cleanup(branch1.unlock)
3619
self.add_cleanup(branch2.unlock)
4090
self.add_cleanup(branch1.lock_read().unlock)
4091
self.add_cleanup(branch2.lock_read().unlock)
3620
4092
last1 = ensure_null(branch1.last_revision())
3621
4093
last2 = ensure_null(branch2.last_revision())
3623
4095
graph = branch1.repository.get_graph(branch2.repository)
3624
4096
base_rev_id = graph.find_unique_lca(last1, last2)
3626
print 'merge base is revision %s' % base_rev_id
4098
self.outf.write(gettext('merge base is revision %s\n') % base_rev_id)
3629
4101
class cmd_merge(Command):
3630
"""Perform a three-way merge.
4102
__doc__ = """Perform a three-way merge.
3632
4104
The source of the merge can be specified either in the form of a branch,
3633
4105
or in the form of a path to a file containing a merge directive generated
3634
4106
with bzr send. If neither is specified, the default is the upstream branch
3635
or the branch most recently merged using --remember.
3637
When merging a branch, by default the tip will be merged. To pick a different
3638
revision, pass --revision. If you specify two values, the first will be used as
3639
BASE and the second one as OTHER. Merging individual revisions, or a subset of
3640
available revisions, like this is commonly referred to as "cherrypicking".
3642
Revision numbers are always relative to the branch being merged.
3644
By default, bzr will try to merge in all new work from the other
3645
branch, automatically determining an appropriate base. If this
3646
fails, you may need to give an explicit base.
4107
or the branch most recently merged using --remember. The source of the
4108
merge may also be specified in the form of a path to a file in another
4109
branch: in this case, only the modifications to that file are merged into
4110
the current working tree.
4112
When merging from a branch, by default bzr will try to merge in all new
4113
work from the other branch, automatically determining an appropriate base
4114
revision. If this fails, you may need to give an explicit base.
4116
To pick a different ending revision, pass "--revision OTHER". bzr will
4117
try to merge in all new work up to and including revision OTHER.
4119
If you specify two values, "--revision BASE..OTHER", only revisions BASE
4120
through OTHER, excluding BASE but including OTHER, will be merged. If this
4121
causes some revisions to be skipped, i.e. if the destination branch does
4122
not already contain revision BASE, such a merge is commonly referred to as
4123
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4124
cherrypicks. The changes look like a normal commit, and the history of the
4125
changes from the other branch is not stored in the commit.
4127
Revision numbers are always relative to the source branch.
3648
4129
Merge will do its best to combine the changes in two branches, but there
3649
4130
are some kinds of problems only a human can fix. When it encounters those,
3653
4134
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
3655
If there is no default branch set, the first merge will set it. After
3656
that, you can omit the branch to use the default. To change the
3657
default, use --remember. The value will only be saved if the remote
3658
location can be accessed.
4136
If there is no default branch set, the first merge will set it (use
4137
--no-remember to avoid setting it). After that, you can omit the branch
4138
to use the default. To change the default, use --remember. The value will
4139
only be saved if the remote location can be accessed.
3660
4141
The results of the merge are placed into the destination working
3661
4142
directory, where they can be reviewed (with bzr diff), tested, and then
3662
4143
committed to record the result of the merge.
3664
4145
merge refuses to run if there are any uncommitted changes, unless
3665
--force is given. The --force option can also be used to create a
4146
--force is given. If --force is given, then the changes from the source
4147
will be merged with the current working tree, including any uncommitted
4148
changes in the tree. The --force option can also be used to create a
3666
4149
merge revision which has more than two parents.
3668
4151
If one would like to merge changes from the working tree of the other
3770
4253
mergeable = None
3772
4255
if uncommitted:
3773
raise errors.BzrCommandError('Cannot use --uncommitted'
3774
' with bundles or merge directives.')
4256
raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4257
' with bundles or merge directives.'))
3776
4259
if revision is not None:
3777
raise errors.BzrCommandError(
3778
'Cannot use -r with merge directives or bundles')
4260
raise errors.BzrCommandError(gettext(
4261
'Cannot use -r with merge directives or bundles'))
3779
4262
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3782
4265
if merger is None and uncommitted:
3783
4266
if revision is not None and len(revision) > 0:
3784
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
4267
raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4268
' --revision at the same time.'))
4269
merger = self.get_merger_from_uncommitted(tree, location, None)
3787
4270
allow_pending = False
3789
4272
if merger is None:
3790
4273
merger, allow_pending = self._get_merger_from_branch(tree,
3791
location, revision, remember, possible_transports, pb)
4274
location, revision, remember, possible_transports, None)
3793
4276
merger.merge_type = merge_type
3794
4277
merger.reprocess = reprocess
3796
4279
self.sanity_check_merger(merger)
3797
4280
if (merger.base_rev_id == merger.other_rev_id and
3798
4281
merger.other_rev_id is not None):
3799
note('Nothing to do.')
4282
# check if location is a nonexistent file (and not a branch) to
4283
# disambiguate the 'Nothing to do'
4284
if merger.interesting_files:
4285
if not merger.other_tree.has_filename(
4286
merger.interesting_files[0]):
4287
note(gettext("merger: ") + str(merger))
4288
raise errors.PathsDoNotExist([location])
4289
note(gettext('Nothing to do.'))
4291
if pull and not preview:
3802
4292
if merger.interesting_files is not None:
3803
raise errors.BzrCommandError('Cannot pull individual files')
4293
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
3804
4294
if (merger.base_rev_id == tree.last_revision()):
3805
4295
result = tree.pull(merger.other_branch, False,
3806
4296
merger.other_rev_id)
3807
4297
result.report(self.outf)
3809
4299
if merger.this_basis is None:
3810
raise errors.BzrCommandError(
4300
raise errors.BzrCommandError(gettext(
3811
4301
"This branch has no commits."
3812
" (perhaps you would prefer 'bzr pull')")
4302
" (perhaps you would prefer 'bzr pull')"))
3814
4304
return self._do_preview(merger)
3815
4305
elif interactive:
3911
4403
if other_revision_id is None:
3912
4404
other_revision_id = _mod_revision.ensure_null(
3913
4405
other_branch.last_revision())
3914
# Remember where we merge from
3915
if ((remember or tree.branch.get_submit_branch() is None) and
3916
user_location is not None):
4406
# Remember where we merge from. We need to remember if:
4407
# - user specify a location (and we don't merge from the parent
4409
# - user ask to remember or there is no previous location set to merge
4410
# from and user didn't ask to *not* remember
4411
if (user_location is not None
4413
or (remember is None
4414
and tree.branch.get_submit_branch() is None)))):
3917
4415
tree.branch.set_submit_branch(other_branch.base)
3918
_merge_tags_if_possible(other_branch, tree.branch)
4416
# Merge tags (but don't set them in the master branch yet, the user
4417
# might revert this merge). Commit will propagate them.
4418
_merge_tags_if_possible(other_branch, tree.branch, ignore_master=True)
3919
4419
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3920
4420
other_revision_id, base_revision_id, other_branch, base_branch)
3921
4421
if other_path != '':
4087
4584
class cmd_revert(Command):
4088
"""Revert files to a previous revision.
4585
__doc__ = """Revert files to a previous revision.
4090
4587
Giving a list of files will revert only those files. Otherwise, all files
4091
4588
will be reverted. If the revision is not specified with '--revision', the
4092
4589
last committed revision is used.
4094
4591
To remove only some changes, without reverting to a prior version, use
4095
merge instead. For example, "merge . --revision -2..-3" will remove the
4096
changes introduced by -2, without affecting the changes introduced by -1.
4097
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
4592
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4593
will remove the changes introduced by the second last commit (-2), without
4594
affecting the changes introduced by the last commit (-1). To remove
4595
certain changes on a hunk-by-hunk basis, see the shelve command.
4099
4597
By default, any files that have been manually changed will be backed up
4100
4598
first. (Files changed only by merge are not backed up.) Backup files have
4269
4765
theirs_only=False,
4270
4766
log_format=None, long=False, short=False, line=False,
4271
4767
show_ids=False, verbose=False, this=False, other=False,
4272
include_merges=False, revision=None, my_revision=None):
4768
include_merged=None, revision=None, my_revision=None,
4770
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4273
4771
from bzrlib.missing import find_unmerged, iter_log_revisions
4274
4772
def message(s):
4275
4773
if not is_quiet():
4276
4774
self.outf.write(s)
4776
if symbol_versioning.deprecated_passed(include_merges):
4777
ui.ui_factory.show_user_warning(
4778
'deprecated_command_option',
4779
deprecated_name='--include-merges',
4780
recommended_name='--include-merged',
4781
deprecated_in_version='2.5',
4782
command=self.invoked_as)
4783
if include_merged is None:
4784
include_merged = include_merges
4786
raise errors.BzrCommandError(gettext(
4787
'{0} and {1} are mutually exclusive').format(
4788
'--include-merges', '--include-merged'))
4789
if include_merged is None:
4790
include_merged = False
4279
4792
mine_only = this
4288
4801
elif theirs_only:
4289
4802
restrict = 'remote'
4291
local_branch = Branch.open_containing(u".")[0]
4804
local_branch = Branch.open_containing(directory)[0]
4805
self.add_cleanup(local_branch.lock_read().unlock)
4292
4807
parent = local_branch.get_parent()
4293
4808
if other_branch is None:
4294
4809
other_branch = parent
4295
4810
if other_branch is None:
4296
raise errors.BzrCommandError("No peer location known"
4811
raise errors.BzrCommandError(gettext("No peer location known"
4298
4813
display_url = urlutils.unescape_for_display(parent,
4299
4814
self.outf.encoding)
4300
message("Using saved parent location: "
4301
+ display_url + "\n")
4815
message(gettext("Using saved parent location: {0}\n").format(
4303
4818
remote_branch = Branch.open(other_branch)
4304
4819
if remote_branch.base == local_branch.base:
4305
4820
remote_branch = local_branch
4822
self.add_cleanup(remote_branch.lock_read().unlock)
4307
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4309
4824
local_revid_range = _revision_range_to_revid_range(
4310
4825
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4315
4828
remote_revid_range = _revision_range_to_revid_range(
4316
4829
_get_revision_range(revision,
4317
4830
remote_branch, self.name()))
4357
4874
if mine_only and not local_extra:
4358
4875
# We checked local, and found nothing extra
4359
message('This branch is up to date.\n')
4876
message(gettext('This branch has no new revisions.\n'))
4360
4877
elif theirs_only and not remote_extra:
4361
4878
# We checked remote, and found nothing extra
4362
message('Other branch is up to date.\n')
4879
message(gettext('Other branch has no new revisions.\n'))
4363
4880
elif not (mine_only or theirs_only or local_extra or
4365
4882
# We checked both branches, and neither one had extra
4367
message("Branches are up to date.\n")
4884
message(gettext("Branches are up to date.\n"))
4368
4885
self.cleanup_now()
4369
4886
if not status_code and parent is None and other_branch is not None:
4370
local_branch.lock_write()
4371
self.add_cleanup(local_branch.unlock)
4887
self.add_cleanup(local_branch.lock_write().unlock)
4372
4888
# handle race conditions - a parent might be set while we run.
4373
4889
if local_branch.get_parent() is None:
4374
4890
local_branch.set_parent(remote_branch.base)
4378
4894
class cmd_pack(Command):
4379
"""Compress the data within a repository."""
4895
__doc__ = """Compress the data within a repository.
4897
This operation compresses the data within a bazaar repository. As
4898
bazaar supports automatic packing of repository, this operation is
4899
normally not required to be done manually.
4901
During the pack operation, bazaar takes a backup of existing repository
4902
data, i.e. pack files. This backup is eventually removed by bazaar
4903
automatically when it is safe to do so. To save disk space by removing
4904
the backed up pack files, the --clean-obsolete-packs option may be
4907
Warning: If you use --clean-obsolete-packs and your machine crashes
4908
during or immediately after repacking, you may be left with a state
4909
where the deletion has been written to disk but the new packs have not
4910
been. In this case the repository may be unusable.
4381
4913
_see_also = ['repositories']
4382
4914
takes_args = ['branch_or_repo?']
4916
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4384
def run(self, branch_or_repo='.'):
4385
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4919
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4920
dir = controldir.ControlDir.open_containing(branch_or_repo)[0]
4387
4922
branch = dir.open_branch()
4388
4923
repository = branch.repository
4389
4924
except errors.NotBranchError:
4390
4925
repository = dir.open_repository()
4926
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4394
4929
class cmd_plugins(Command):
4395
"""List the installed plugins.
4930
__doc__ = """List the installed plugins.
4397
4932
This command displays the list of installed plugins including
4398
4933
version of plugin and a short description of each.
4415
4950
@display_command
4416
4951
def run(self, verbose=False):
4417
import bzrlib.plugin
4418
from inspect import getdoc
4420
for name, plugin in bzrlib.plugin.plugins().items():
4421
version = plugin.__version__
4422
if version == 'unknown':
4424
name_ver = '%s %s' % (name, version)
4425
d = getdoc(plugin.module)
4427
doc = d.split('\n')[0]
4429
doc = '(no description)'
4430
result.append((name_ver, doc, plugin.path()))
4431
for name_ver, doc, path in sorted(result):
4952
from bzrlib import plugin
4953
# Don't give writelines a generator as some codecs don't like that
4954
self.outf.writelines(
4955
list(plugin.describe_plugins(show_paths=verbose)))
4439
4958
class cmd_testament(Command):
4440
"""Show testament (signing-form) of a revision."""
4959
__doc__ = """Show testament (signing-form) of a revision."""
4441
4960
takes_options = [
4443
4962
Option('long', help='Produce long-format testament.'),
4486
5004
Option('long', help='Show commit date in annotations.'),
4490
5009
encoding_type = 'exact'
4492
5011
@display_command
4493
5012
def run(self, filename, all=False, long=False, revision=None,
4495
from bzrlib.annotate import annotate_file, annotate_file_tree
5013
show_ids=False, directory=None):
5014
from bzrlib.annotate import (
4496
5017
wt, branch, relpath = \
4497
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
5018
_open_directory_or_containing_tree_or_branch(filename, directory)
4498
5019
if wt is not None:
4500
self.add_cleanup(wt.unlock)
5020
self.add_cleanup(wt.lock_read().unlock)
4503
self.add_cleanup(branch.unlock)
5022
self.add_cleanup(branch.lock_read().unlock)
4504
5023
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4506
self.add_cleanup(tree.unlock)
5024
self.add_cleanup(tree.lock_read().unlock)
5025
if wt is not None and revision is None:
4508
5026
file_id = wt.path2id(relpath)
4510
5028
file_id = tree.path2id(relpath)
4511
5029
if file_id is None:
4512
5030
raise errors.NotVersionedError(filename)
4513
file_version = tree.inventory[file_id].revision
4514
5031
if wt is not None and revision is None:
4515
5032
# If there is a tree and we're not annotating historical
4516
5033
# versions, annotate the working tree's content.
4517
5034
annotate_file_tree(wt, file_id, self.outf, long, all,
4518
5035
show_ids=show_ids)
4520
annotate_file(branch, file_version, file_id, long, all, self.outf,
5037
annotate_file_tree(tree, file_id, self.outf, long, all,
5038
show_ids=show_ids, branch=branch)
4524
5041
class cmd_re_sign(Command):
4525
"""Create a digital signature for an existing revision."""
5042
__doc__ = """Create a digital signature for an existing revision."""
4526
5043
# TODO be able to replace existing ones.
4528
5045
hidden = True # is this right ?
4529
5046
takes_args = ['revision_id*']
4530
takes_options = ['revision']
5047
takes_options = ['directory', 'revision']
4532
def run(self, revision_id_list=None, revision=None):
5049
def run(self, revision_id_list=None, revision=None, directory=u'.'):
4533
5050
if revision_id_list is not None and revision is not None:
4534
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
5051
raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
4535
5052
if revision_id_list is None and revision is None:
4536
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4537
b = WorkingTree.open_containing(u'.')[0].branch
4539
self.add_cleanup(b.unlock)
5053
raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
5054
b = WorkingTree.open_containing(directory)[0].branch
5055
self.add_cleanup(b.lock_write().unlock)
4540
5056
return self._run(b, revision_id_list, revision)
4542
5058
def _run(self, b, revision_id_list, revision):
4543
5059
import bzrlib.gpg as gpg
4544
gpg_strategy = gpg.GPGStrategy(b.get_config())
5060
gpg_strategy = gpg.GPGStrategy(b.get_config_stack())
4545
5061
if revision_id_list is not None:
4546
5062
b.repository.start_write_group()
4601
5118
_see_also = ['checkouts', 'unbind']
4602
5119
takes_args = ['location?']
5120
takes_options = ['directory']
4605
def run(self, location=None):
4606
b, relpath = Branch.open_containing(u'.')
5122
def run(self, location=None, directory=u'.'):
5123
b, relpath = Branch.open_containing(directory)
4607
5124
if location is None:
4609
5126
location = b.get_old_bound_location()
4610
5127
except errors.UpgradeRequired:
4611
raise errors.BzrCommandError('No location supplied. '
4612
'This format does not remember old locations.')
5128
raise errors.BzrCommandError(gettext('No location supplied. '
5129
'This format does not remember old locations.'))
4614
5131
if location is None:
4615
raise errors.BzrCommandError('No location supplied and no '
4616
'previous location known')
5132
if b.get_bound_location() is not None:
5133
raise errors.BzrCommandError(gettext('Branch is already bound'))
5135
raise errors.BzrCommandError(gettext('No location supplied '
5136
'and no previous location known'))
4617
5137
b_other = Branch.open(location)
4619
5139
b.bind(b_other)
4620
5140
except errors.DivergedBranches:
4621
raise errors.BzrCommandError('These branches have diverged.'
4622
' Try merging, and then bind again.')
5141
raise errors.BzrCommandError(gettext('These branches have diverged.'
5142
' Try merging, and then bind again.'))
4623
5143
if b.get_config().has_explicit_nickname():
4624
5144
b.nick = b_other.nick
4627
5147
class cmd_unbind(Command):
4628
"""Convert the current checkout into a regular branch.
5148
__doc__ = """Convert the current checkout into a regular branch.
4630
5150
After unbinding, the local branch is considered independent and subsequent
4631
5151
commits will be local only.
4688
5209
b = control.open_branch()
4690
5211
if tree is not None:
4692
self.add_cleanup(tree.unlock)
5212
self.add_cleanup(tree.lock_write().unlock)
4695
self.add_cleanup(b.unlock)
4696
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
5214
self.add_cleanup(b.lock_write().unlock)
5215
return self._run(b, tree, dry_run, verbose, revision, force,
4698
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
5218
def _run(self, b, tree, dry_run, verbose, revision, force, local,
4699
5220
from bzrlib.log import log_formatter, show_log
4700
5221
from bzrlib.uncommit import uncommit
4731
5252
end_revision=last_revno)
4734
print 'Dry-run, pretending to remove the above revisions.'
4736
val = raw_input('Press <enter> to continue')
5255
self.outf.write(gettext('Dry-run, pretending to remove'
5256
' the above revisions.\n'))
4738
print 'The above revision(s) will be removed.'
4740
val = raw_input('Are you sure [y/N]? ')
4741
if val.lower() not in ('y', 'yes'):
5258
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5261
if not ui.ui_factory.confirm_action(
5262
gettext(u'Uncommit these revisions'),
5263
'bzrlib.builtins.uncommit',
5265
self.outf.write(gettext('Canceled\n'))
4745
5268
mutter('Uncommitting from {%s} to {%s}',
4746
5269
last_rev_id, rev_id)
4747
5270
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4748
revno=revno, local=local)
4749
note('You can restore the old tip by running:\n'
4750
' bzr pull . -r revid:%s', last_rev_id)
5271
revno=revno, local=local, keep_tags=keep_tags)
5272
self.outf.write(gettext('You can restore the old tip by running:\n'
5273
' bzr pull . -r revid:%s\n') % last_rev_id)
4753
5276
class cmd_break_lock(Command):
4754
"""Break a dead lock on a repository, branch or working directory.
5277
__doc__ = """Break a dead lock.
5279
This command breaks a lock on a repository, branch, working directory or
4756
5282
CAUTION: Locks should only be broken when you are sure that the process
4757
5283
holding the lock has been stopped.
4764
5290
bzr break-lock bzr+ssh://example.com/bzr/foo
5291
bzr break-lock --conf ~/.bazaar
4766
5294
takes_args = ['location?']
5297
help='LOCATION is the directory where the config lock is.'),
5299
help='Do not ask for confirmation before breaking the lock.'),
4768
def run(self, location=None, show=False):
5302
def run(self, location=None, config=False, force=False):
4769
5303
if location is None:
4770
5304
location = u'.'
4771
control, relpath = bzrdir.BzrDir.open_containing(location)
4773
control.break_lock()
4774
except NotImplementedError:
5306
ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5308
{'bzrlib.lockdir.break': True})
5310
conf = _mod_config.LockableConfig(file_name=location)
5313
control, relpath = controldir.ControlDir.open_containing(location)
5315
control.break_lock()
5316
except NotImplementedError:
4778
5320
class cmd_wait_until_signalled(Command):
4779
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
5321
__doc__ = """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4781
5323
This just prints a line to signal when it is ready, then blocks on stdin.
4841
5384
return host, port
4843
5386
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4845
from bzrlib.transport import get_transport, transport_server_registry
5387
protocol=None, client_timeout=None):
5388
from bzrlib import transport
4846
5389
if directory is None:
4847
5390
directory = os.getcwd()
4848
5391
if protocol is None:
4849
protocol = transport_server_registry.get()
5392
protocol = transport.transport_server_registry.get()
4850
5393
host, port = self.get_host_and_port(port)
4851
url = urlutils.local_path_to_url(directory)
5394
url = transport.location_to_url(directory)
4852
5395
if not allow_writes:
4853
5396
url = 'readonly+' + url
4854
transport = get_transport(url)
4855
protocol(transport, host, port, inet)
5397
t = transport.get_transport_from_url(url)
5399
protocol(t, host, port, inet, client_timeout)
5400
except TypeError, e:
5401
# We use symbol_versioning.deprecated_in just so that people
5402
# grepping can find it here.
5403
# symbol_versioning.deprecated_in((2, 5, 0))
5404
symbol_versioning.warn(
5405
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5406
'Most likely it needs to be updated to support a'
5407
' "timeout" parameter (added in bzr 2.5.0)'
5408
% (e, protocol.__module__, protocol),
5410
protocol(t, host, port, inet)
4858
5413
class cmd_join(Command):
4859
"""Combine a tree into its containing tree.
5414
__doc__ = """Combine a tree into its containing tree.
4861
5416
This command requires the target tree to be in a rich-root format.
4891
5446
except errors.BadReferenceTarget, e:
4892
5447
# XXX: Would be better to just raise a nicely printable
4893
5448
# exception from the real origin. Also below. mbp 20070306
4894
raise errors.BzrCommandError("Cannot join %s. %s" %
5449
raise errors.BzrCommandError(
5450
gettext("Cannot join {0}. {1}").format(tree, e.reason))
4898
5453
containing_tree.subsume(sub_tree)
4899
5454
except errors.BadSubsumeSource, e:
4900
raise errors.BzrCommandError("Cannot join %s. %s" %
5455
raise errors.BzrCommandError(
5456
gettext("Cannot join {0}. {1}").format(tree, e.reason))
4904
5459
class cmd_split(Command):
4905
"""Split a subdirectory of a tree into a separate tree.
5460
__doc__ = """Split a subdirectory of a tree into a separate tree.
4907
5462
This command will produce a target tree in a format that supports
4908
5463
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
5232
5795
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5233
5796
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5798
If no tag name is specified it will be determined through the
5799
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5800
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5236
5804
_see_also = ['commit', 'tags']
5237
takes_args = ['tag_name']
5805
takes_args = ['tag_name?']
5238
5806
takes_options = [
5239
5807
Option('delete',
5240
5808
help='Delete this tag rather than placing it.',
5243
help='Branch in which to place the tag.',
5810
custom_help('directory',
5811
help='Branch in which to place the tag.'),
5247
5812
Option('force',
5248
5813
help='Replace existing tags.',
5253
def run(self, tag_name,
5818
def run(self, tag_name=None,
5259
5824
branch, relpath = Branch.open_containing(directory)
5261
self.add_cleanup(branch.unlock)
5825
self.add_cleanup(branch.lock_write().unlock)
5827
if tag_name is None:
5828
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5263
5829
branch.tags.delete_tag(tag_name)
5264
self.outf.write('Deleted tag %s.\n' % tag_name)
5830
note(gettext('Deleted tag %s.') % tag_name)
5267
5833
if len(revision) != 1:
5268
raise errors.BzrCommandError(
5834
raise errors.BzrCommandError(gettext(
5269
5835
"Tags can only be placed on a single revision, "
5271
5837
revision_id = revision[0].as_revision_id(branch)
5273
5839
revision_id = branch.last_revision()
5274
if (not force) and branch.tags.has_tag(tag_name):
5840
if tag_name is None:
5841
tag_name = branch.automatic_tag_name(revision_id)
5842
if tag_name is None:
5843
raise errors.BzrCommandError(gettext(
5844
"Please specify a tag name."))
5846
existing_target = branch.tags.lookup_tag(tag_name)
5847
except errors.NoSuchTag:
5848
existing_target = None
5849
if not force and existing_target not in (None, revision_id):
5275
5850
raise errors.TagAlreadyExists(tag_name)
5276
branch.tags.set_tag(tag_name, revision_id)
5277
self.outf.write('Created tag %s.\n' % tag_name)
5851
if existing_target == revision_id:
5852
note(gettext('Tag %s already exists for that revision.') % tag_name)
5854
branch.tags.set_tag(tag_name, revision_id)
5855
if existing_target is None:
5856
note(gettext('Created tag %s.') % tag_name)
5858
note(gettext('Updated tag %s.') % tag_name)
5280
5861
class cmd_tags(Command):
5862
__doc__ = """List tags.
5283
5864
This command shows a table of tag names and the revisions they reference.
5286
5867
_see_also = ['tag']
5287
5868
takes_options = [
5289
help='Branch whose tags should be displayed.',
5293
RegistryOption.from_kwargs('sort',
5869
custom_help('directory',
5870
help='Branch whose tags should be displayed.'),
5871
RegistryOption('sort',
5294
5872
'Sort tags by different criteria.', title='Sorting',
5295
alpha='Sort tags lexicographically (default).',
5296
time='Sort tags chronologically.',
5873
lazy_registry=('bzrlib.tag', 'tag_sort_methods')
5302
5879
@display_command
5880
def run(self, directory='.', sort=None, show_ids=False, revision=None):
5881
from bzrlib.tag import tag_sort_methods
5309
5882
branch, relpath = Branch.open_containing(directory)
5311
5884
tags = branch.tags.get_tag_dict().items()
5316
self.add_cleanup(branch.unlock)
5888
self.add_cleanup(branch.lock_read().unlock)
5318
graph = branch.repository.get_graph()
5319
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5320
revid1, revid2 = rev1.rev_id, rev2.rev_id
5321
# only show revisions between revid1 and revid2 (inclusive)
5322
tags = [(tag, revid) for tag, revid in tags if
5323
graph.is_between(revid, revid1, revid2)]
5326
elif sort == 'time':
5328
for tag, revid in tags:
5330
revobj = branch.repository.get_revision(revid)
5331
except errors.NoSuchRevision:
5332
timestamp = sys.maxint # place them at the end
5334
timestamp = revobj.timestamp
5335
timestamps[revid] = timestamp
5336
tags.sort(key=lambda x: timestamps[x[1]])
5890
# Restrict to the specified range
5891
tags = self._tags_for_range(branch, revision)
5893
sort = tag_sort_methods.get()
5337
5895
if not show_ids:
5338
5896
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5339
5897
for index, (tag, revid) in enumerate(tags):
5350
5910
for tag, revspec in tags:
5351
5911
self.outf.write('%-20s %s\n' % (tag, revspec))
5913
def _tags_for_range(self, branch, revision):
5915
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5916
revid1, revid2 = rev1.rev_id, rev2.rev_id
5917
# _get_revision_range will always set revid2 if it's not specified.
5918
# If revid1 is None, it means we want to start from the branch
5919
# origin which is always a valid ancestor. If revid1 == revid2, the
5920
# ancestry check is useless.
5921
if revid1 and revid1 != revid2:
5922
# FIXME: We really want to use the same graph than
5923
# branch.iter_merge_sorted_revisions below, but this is not
5924
# easily available -- vila 2011-09-23
5925
if branch.repository.get_graph().is_ancestor(revid2, revid1):
5926
# We don't want to output anything in this case...
5928
# only show revisions between revid1 and revid2 (inclusive)
5929
tagged_revids = branch.tags.get_reverse_tag_dict()
5931
for r in branch.iter_merge_sorted_revisions(
5932
start_revision_id=revid2, stop_revision_id=revid1,
5933
stop_rule='include'):
5934
revid_tags = tagged_revids.get(r[0], None)
5936
found.extend([(tag, r[0]) for tag in revid_tags])
5354
5940
class cmd_reconfigure(Command):
5355
"""Reconfigure the type of a bzr directory.
5941
__doc__ = """Reconfigure the type of a bzr directory.
5357
5943
A target configuration must be specified.
5369
5955
takes_args = ['location?']
5370
5956
takes_options = [
5371
5957
RegistryOption.from_kwargs(
5373
title='Target type',
5374
help='The type to reconfigure the directory to.',
5960
help='The relation between branch and tree.',
5375
5961
value_switches=True, enum_switch=False,
5376
5962
branch='Reconfigure to be an unbound branch with no working tree.',
5377
5963
tree='Reconfigure to be an unbound branch with a working tree.',
5378
5964
checkout='Reconfigure to be a bound branch with a working tree.',
5379
5965
lightweight_checkout='Reconfigure to be a lightweight'
5380
5966
' checkout (with no local history).',
5968
RegistryOption.from_kwargs(
5970
title='Repository type',
5971
help='Location fo the repository.',
5972
value_switches=True, enum_switch=False,
5381
5973
standalone='Reconfigure to be a standalone branch '
5382
5974
'(i.e. stop using shared repository).',
5383
5975
use_shared='Reconfigure to use a shared repository.',
5977
RegistryOption.from_kwargs(
5979
title='Trees in Repository',
5980
help='Whether new branches in the repository have trees.',
5981
value_switches=True, enum_switch=False,
5384
5982
with_trees='Reconfigure repository to create '
5385
5983
'working trees on branches by default.',
5386
5984
with_no_trees='Reconfigure repository to not create '
5413
6011
# At the moment you can use --stacked-on and a different
5414
6012
# reconfiguration shape at the same time; there seems no good reason
5416
if target_type is None:
6014
if (tree_type is None and
6015
repository_type is None and
6016
repository_trees is None):
5417
6017
if stacked_on or unstacked:
5420
raise errors.BzrCommandError('No target configuration '
5422
elif target_type == 'branch':
6020
raise errors.BzrCommandError(gettext('No target configuration '
6022
reconfiguration = None
6023
if tree_type == 'branch':
5423
6024
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5424
elif target_type == 'tree':
6025
elif tree_type == 'tree':
5425
6026
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5426
elif target_type == 'checkout':
6027
elif tree_type == 'checkout':
5427
6028
reconfiguration = reconfigure.Reconfigure.to_checkout(
5428
6029
directory, bind_to)
5429
elif target_type == 'lightweight-checkout':
6030
elif tree_type == 'lightweight-checkout':
5430
6031
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5431
6032
directory, bind_to)
5432
elif target_type == 'use-shared':
6034
reconfiguration.apply(force)
6035
reconfiguration = None
6036
if repository_type == 'use-shared':
5433
6037
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5434
elif target_type == 'standalone':
6038
elif repository_type == 'standalone':
5435
6039
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5436
elif target_type == 'with-trees':
6041
reconfiguration.apply(force)
6042
reconfiguration = None
6043
if repository_trees == 'with-trees':
5437
6044
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5438
6045
directory, True)
5439
elif target_type == 'with-no-trees':
6046
elif repository_trees == 'with-no-trees':
5440
6047
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5441
6048
directory, False)
5442
reconfiguration.apply(force)
6050
reconfiguration.apply(force)
6051
reconfiguration = None
5445
6054
class cmd_switch(Command):
5446
"""Set the branch of a checkout and update.
6055
__doc__ = """Set the branch of a checkout and update.
5448
6057
For lightweight checkouts, this changes the branch being referenced.
5449
6058
For heavyweight checkouts, this checks that there are no local commits
5493
6103
had_explicit_nick = False
5494
6104
if create_branch:
5495
6105
if branch is None:
5496
raise errors.BzrCommandError('cannot create branch without'
6106
raise errors.BzrCommandError(gettext('cannot create branch without'
5498
6108
to_location = directory_service.directories.dereference(
5500
6110
if '/' not in to_location and '\\' not in to_location:
5501
6111
# This path is meant to be relative to the existing branch
5502
6112
this_url = self._get_branch_location(control_dir)
5503
to_location = urlutils.join(this_url, '..', to_location)
6113
# Perhaps the target control dir supports colocated branches?
6115
root = controldir.ControlDir.open(this_url,
6116
possible_transports=[control_dir.user_transport])
6117
except errors.NotBranchError:
6120
colocated = root._format.colocated_branches
6122
to_location = urlutils.join_segment_parameters(this_url,
6123
{"branch": urlutils.escape(to_location)})
6125
to_location = urlutils.join(
6126
this_url, '..', urlutils.escape(to_location))
5504
6127
to_branch = branch.bzrdir.sprout(to_location,
5505
6128
possible_transports=[branch.bzrdir.root_transport],
5506
6129
source_branch=branch).open_branch()
6131
# Perhaps it's a colocated branch?
5509
to_branch = Branch.open(to_location)
5510
except errors.NotBranchError:
5511
this_url = self._get_branch_location(control_dir)
5512
to_branch = Branch.open(
5513
urlutils.join(this_url, '..', to_location))
6133
to_branch = control_dir.open_branch(to_location)
6134
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6136
to_branch = Branch.open(to_location)
6137
except errors.NotBranchError:
6138
this_url = self._get_branch_location(control_dir)
6139
to_branch = Branch.open(
6141
this_url, '..', urlutils.escape(to_location)))
5514
6142
if revision is not None:
5515
6143
revision = revision.as_revision_id(to_branch)
5516
6144
switch.switch(control_dir, to_branch, force, revision_id=revision)
5517
6145
if had_explicit_nick:
5518
6146
branch = control_dir.open_branch() #get the new branch!
5519
6147
branch.nick = to_branch.nick
5520
note('Switched to branch: %s',
6148
note(gettext('Switched to branch: %s'),
5521
6149
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5523
6151
def _get_branch_location(self, control_dir):
5628
tree, file_list = tree_files(file_list, apply_view=False)
6256
tree, file_list = WorkingTree.open_containing_paths(file_list,
5629
6258
current_view, view_dict = tree.views.get_view_info()
5630
6259
if name is None:
5631
6260
name = current_view
5634
raise errors.BzrCommandError(
5635
"Both --delete and a file list specified")
6263
raise errors.BzrCommandError(gettext(
6264
"Both --delete and a file list specified"))
5637
raise errors.BzrCommandError(
5638
"Both --delete and --switch specified")
6266
raise errors.BzrCommandError(gettext(
6267
"Both --delete and --switch specified"))
5640
6269
tree.views.set_view_info(None, {})
5641
self.outf.write("Deleted all views.\n")
6270
self.outf.write(gettext("Deleted all views.\n"))
5642
6271
elif name is None:
5643
raise errors.BzrCommandError("No current view to delete")
6272
raise errors.BzrCommandError(gettext("No current view to delete"))
5645
6274
tree.views.delete_view(name)
5646
self.outf.write("Deleted '%s' view.\n" % name)
6275
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5649
raise errors.BzrCommandError(
5650
"Both --switch and a file list specified")
6278
raise errors.BzrCommandError(gettext(
6279
"Both --switch and a file list specified"))
5652
raise errors.BzrCommandError(
5653
"Both --switch and --all specified")
6281
raise errors.BzrCommandError(gettext(
6282
"Both --switch and --all specified"))
5654
6283
elif switch == 'off':
5655
6284
if current_view is None:
5656
raise errors.BzrCommandError("No current view to disable")
6285
raise errors.BzrCommandError(gettext("No current view to disable"))
5657
6286
tree.views.set_view_info(None, view_dict)
5658
self.outf.write("Disabled '%s' view.\n" % (current_view))
6287
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5660
6289
tree.views.set_view_info(switch, view_dict)
5661
6290
view_str = views.view_display_str(tree.views.lookup_view())
5662
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6291
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5665
self.outf.write('Views defined:\n')
6294
self.outf.write(gettext('Views defined:\n'))
5666
6295
for view in sorted(view_dict):
5667
6296
if view == current_view:
5671
6300
view_str = views.view_display_str(view_dict[view])
5672
6301
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5674
self.outf.write('No views defined.\n')
6303
self.outf.write(gettext('No views defined.\n'))
5675
6304
elif file_list:
5676
6305
if name is None:
5677
6306
# No name given and no current view set
5679
6308
elif name == 'off':
5680
raise errors.BzrCommandError(
5681
"Cannot change the 'off' pseudo view")
6309
raise errors.BzrCommandError(gettext(
6310
"Cannot change the 'off' pseudo view"))
5682
6311
tree.views.set_view(name, sorted(file_list))
5683
6312
view_str = views.view_display_str(tree.views.lookup_view())
5684
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6313
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5686
6315
# list the files
5687
6316
if name is None:
5688
6317
# No name given and no current view set
5689
self.outf.write('No current view.\n')
6318
self.outf.write(gettext('No current view.\n'))
5691
6320
view_str = views.view_display_str(tree.views.lookup_view(name))
5692
self.outf.write("'%s' view is: %s\n" % (name, view_str))
6321
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5695
6324
class cmd_hooks(Command):
6325
__doc__ = """Show hooks."""
5709
6338
self.outf.write(" %s\n" %
5710
6339
(some_hooks.get_hook_name(hook),))
5712
self.outf.write(" <no hooks installed>\n")
6341
self.outf.write(gettext(" <no hooks installed>\n"))
6344
class cmd_remove_branch(Command):
6345
__doc__ = """Remove a branch.
6347
This will remove the branch from the specified location but
6348
will keep any working tree or repository in place.
6352
Remove the branch at repo/trunk::
6354
bzr remove-branch repo/trunk
6358
takes_args = ["location?"]
6360
aliases = ["rmbranch"]
6362
def run(self, location=None):
6363
if location is None:
6365
branch = Branch.open_containing(location)[0]
6366
branch.bzrdir.destroy_branch()
5715
6369
class cmd_shelve(Command):
5716
"""Temporarily set aside some changes from the current tree.
6370
__doc__ = """Temporarily set aside some changes from the current tree.
5718
6372
Shelve allows you to temporarily put changes you've made "on the shelf",
5719
6373
ie. out of the way, until a later time when you can bring them back from
5751
6418
Option('destroy',
5752
6419
help='Destroy removed changes instead of shelving them.'),
5754
_see_also = ['unshelve']
6421
_see_also = ['unshelve', 'configuration']
5756
6423
def run(self, revision=None, all=False, file_list=None, message=None,
5757
writer=None, list=False, destroy=False):
6424
writer=None, list=False, destroy=False, directory=None):
5759
return self.run_for_list()
6426
return self.run_for_list(directory=directory)
5760
6427
from bzrlib.shelf_ui import Shelver
5761
6428
if writer is None:
5762
6429
writer = bzrlib.option.diff_writer_registry.get()
5764
6431
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5765
file_list, message, destroy=destroy)
6432
file_list, message, destroy=destroy, directory=directory)
5843
6513
' deleting them.'),
5844
6514
Option('force', help='Do not prompt before deleting.')]
5845
6515
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6516
force=False, directory=u'.'):
5847
6517
from bzrlib.clean_tree import clean_tree
5848
6518
if not (unknown or ignored or detritus):
5852
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
5853
dry_run=dry_run, no_prompt=force)
6522
clean_tree(directory, unknown=unknown, ignored=ignored,
6523
detritus=detritus, dry_run=dry_run, no_prompt=force)
5856
6526
class cmd_reference(Command):
5857
"""list, view and set branch locations for nested trees.
6527
__doc__ = """list, view and set branch locations for nested trees.
5859
6529
If no arguments are provided, lists the branch locations for nested trees.
5860
6530
If one argument is provided, display the branch location for that tree.
5900
6570
self.outf.write('%s %s\n' % (path, location))
5903
# these get imported and then picked up by the scan for cmd_*
5904
# TODO: Some more consistent way to split command definitions across files;
5905
# we do need to load at least some information about them to know of
5906
# aliases. ideally we would avoid loading the implementation until the
5907
# details were needed.
5908
from bzrlib.cmd_version_info import cmd_version_info
5909
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5910
from bzrlib.bundle.commands import (
5913
from bzrlib.foreign import cmd_dpush
5914
from bzrlib.sign_my_commits import cmd_sign_my_commits
5915
from bzrlib.weave_commands import cmd_versionedfile_list, \
5916
cmd_weave_plan_merge, cmd_weave_merge_text
6573
class cmd_export_pot(Command):
6574
__doc__ = """Export command helps and error messages in po format."""
6577
takes_options = [Option('plugin',
6578
help='Export help text from named command '\
6579
'(defaults to all built in commands).',
6581
Option('include-duplicates',
6582
help='Output multiple copies of the same msgid '
6583
'string if it appears more than once.'),
6586
def run(self, plugin=None, include_duplicates=False):
6587
from bzrlib.export_pot import export_pot
6588
export_pot(self.outf, plugin, include_duplicates)
6591
def _register_lazy_builtins():
6592
# register lazy builtins from other modules; called at startup and should
6593
# be only called once.
6594
for (name, aliases, module_name) in [
6595
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6596
('cmd_config', [], 'bzrlib.config'),
6597
('cmd_dpush', [], 'bzrlib.foreign'),
6598
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6599
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6600
('cmd_conflicts', [], 'bzrlib.conflicts'),
6601
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6602
('cmd_verify_signatures', [],
6603
'bzrlib.commit_signature_commands'),
6604
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6606
builtin_command_registry.register_lazy(name, aliases, module_name)