326
339
def run(self, revision_id=None, revision=None, directory=u'.'):
327
340
if revision_id is not None and revision is not None:
328
raise errors.BzrCommandError('You can only supply one of'
329
' revision_id or --revision')
341
raise errors.BzrCommandError(gettext('You can only supply one of'
342
' revision_id or --revision'))
330
343
if revision_id is None and revision is None:
331
raise errors.BzrCommandError('You must supply either'
332
' --revision or a revision_id')
344
raise errors.BzrCommandError(gettext('You must supply either'
345
' --revision or a revision_id'))
334
b = bzrdir.BzrDir.open_containing_tree_or_branch(directory)[1]
347
b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
336
349
revisions = b.repository.revisions
337
350
if revisions is None:
338
raise errors.BzrCommandError('Repository %r does not support '
339
'access to raw revision texts')
351
raise errors.BzrCommandError(gettext('Repository %r does not support '
352
'access to raw revision texts'))
341
354
b.repository.lock_read()
549
561
_see_also = ['info']
550
562
takes_args = ['location?']
551
563
takes_options = [
552
Option('tree', help='Show revno of working tree'),
564
Option('tree', help='Show revno of working tree.'),
556
def run(self, tree=False, location=u'.'):
569
def run(self, tree=False, location=u'.', revision=None):
570
if revision is not None and tree:
571
raise errors.BzrCommandError(gettext("--tree and --revision can "
572
"not be used together"))
559
576
wt = WorkingTree.open_containing(location)[0]
560
577
self.add_cleanup(wt.lock_read().unlock)
561
578
except (errors.NoWorkingTree, errors.NotLocalUrl):
562
579
raise errors.NoWorkingTree(location)
563
581
revid = wt.last_revision()
565
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
566
except errors.NoSuchRevision:
568
revno = ".".join(str(n) for n in revno_t)
570
583
b = Branch.open_containing(location)[0]
571
584
self.add_cleanup(b.lock_read().unlock)
586
if len(revision) != 1:
587
raise errors.BzrCommandError(gettext(
588
"Tags can only be placed on a single revision, "
590
revid = revision[0].as_revision_id(b)
592
revid = b.last_revision()
594
revno_t = b.revision_id_to_dotted_revno(revid)
595
except errors.NoSuchRevision:
597
revno = ".".join(str(n) for n in revno_t)
573
598
self.cleanup_now()
574
self.outf.write(str(revno) + '\n')
599
self.outf.write(revno + '\n')
577
602
class cmd_revision_info(Command):
725
758
takes_args = ['dir+']
762
help='No error if existing, make parent directories as needed.',
726
766
encoding_type = 'replace'
728
def run(self, dir_list):
730
wt, dd = WorkingTree.open_containing(d)
731
base = os.path.dirname(dd)
732
id = wt.path2id(base)
736
self.outf.write('added %s\n' % d)
769
def add_file_with_parents(cls, wt, relpath):
770
if wt.path2id(relpath) is not None:
772
cls.add_file_with_parents(wt, osutils.dirname(relpath))
776
def add_file_single(cls, wt, relpath):
779
def run(self, dir_list, parents=False):
781
add_file = self.add_file_with_parents
783
add_file = self.add_file_single
785
wt, relpath = WorkingTree.open_containing(dir)
790
if e.errno != errno.EEXIST:
738
raise errors.NotVersionedError(path=base)
794
add_file(wt, relpath)
796
self.outf.write(gettext('added %s\n') % dir)
741
799
class cmd_relpath(Command):
847
906
return self.run_auto(names_list, after, dry_run)
849
raise errors.BzrCommandError('--dry-run requires --auto.')
908
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
850
909
if names_list is None:
852
911
if len(names_list) < 2:
853
raise errors.BzrCommandError("missing file argument")
912
raise errors.BzrCommandError(gettext("missing file argument"))
854
913
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
914
for file_name in rel_names[0:-1]:
916
raise errors.BzrCommandError(gettext("can not move root of branch"))
855
917
self.add_cleanup(tree.lock_tree_write().unlock)
856
918
self._run(tree, names_list, rel_names, after)
858
920
def run_auto(self, names_list, after, dry_run):
859
921
if names_list is not None and len(names_list) > 1:
860
raise errors.BzrCommandError('Only one path may be specified to'
922
raise errors.BzrCommandError(gettext('Only one path may be specified to'
863
raise errors.BzrCommandError('--after cannot be specified with'
925
raise errors.BzrCommandError(gettext('--after cannot be specified with'
865
927
work_tree, file_list = WorkingTree.open_containing_paths(
866
928
names_list, default_directory='.')
867
929
self.add_cleanup(work_tree.lock_tree_write().unlock)
1175
1244
# error by the feedback given to them. RBC 20080227.
1176
1245
stacked_on = parent_url
1177
1246
if not stacked_on:
1178
raise errors.BzrCommandError(
1179
"Could not determine branch to refer to.")
1247
raise errors.BzrCommandError(gettext(
1248
"Could not determine branch to refer to."))
1181
1250
# Get the destination location
1182
1251
if location is None:
1183
1252
stored_loc = br_from.get_push_location()
1184
1253
if stored_loc is None:
1185
raise errors.BzrCommandError(
1186
"No push location known or specified.")
1254
parent_loc = br_from.get_parent()
1256
raise errors.BzrCommandError(gettext(
1257
"No push location known or specified. To push to the "
1258
"parent branch (at %s), use 'bzr push :parent'." %
1259
urlutils.unescape_for_display(parent_loc,
1260
self.outf.encoding)))
1262
raise errors.BzrCommandError(gettext(
1263
"No push location known or specified."))
1188
1265
display_url = urlutils.unescape_for_display(stored_loc,
1189
1266
self.outf.encoding)
1190
self.outf.write("Using saved push location: %s\n" % display_url)
1267
note(gettext("Using saved push location: %s") % display_url)
1191
1268
location = stored_loc
1193
1270
_show_push_branch(br_from, revision_id, location, self.outf,
1271
1348
revision_id = br_from.last_revision()
1272
1349
if to_location is None:
1273
to_location = urlutils.derive_to_location(from_location)
1350
to_location = getattr(br_from, "name", None)
1351
if to_location is None:
1352
to_location = urlutils.derive_to_location(from_location)
1274
1353
to_transport = transport.get_transport(to_location)
1276
1355
to_transport.mkdir('.')
1277
1356
except errors.FileExists:
1278
if not use_existing_dir:
1279
raise errors.BzrCommandError('Target directory "%s" '
1280
'already exists.' % to_location)
1358
to_dir = controldir.ControlDir.open_from_transport(
1360
except errors.NotBranchError:
1361
if not use_existing_dir:
1362
raise errors.BzrCommandError(gettext('Target directory "%s" '
1363
'already exists.') % to_location)
1283
bzrdir.BzrDir.open_from_transport(to_transport)
1368
to_dir.open_branch()
1284
1369
except errors.NotBranchError:
1287
1372
raise errors.AlreadyBranchError(to_location)
1288
1373
except errors.NoSuchFile:
1289
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1374
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1292
# preserve whatever source format we have.
1293
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1294
possible_transports=[to_transport],
1295
accelerator_tree=accelerator_tree,
1296
hardlink=hardlink, stacked=stacked,
1297
force_new_repo=standalone,
1298
create_tree_if_local=not no_tree,
1299
source_branch=br_from)
1300
branch = dir.open_branch()
1301
except errors.NoSuchRevision:
1302
to_transport.delete_tree('.')
1303
msg = "The branch %s has no revision %s." % (from_location,
1305
raise errors.BzrCommandError(msg)
1380
# preserve whatever source format we have.
1381
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1382
possible_transports=[to_transport],
1383
accelerator_tree=accelerator_tree,
1384
hardlink=hardlink, stacked=stacked,
1385
force_new_repo=standalone,
1386
create_tree_if_local=not no_tree,
1387
source_branch=br_from)
1388
branch = to_dir.open_branch(
1389
possible_transports=[
1390
br_from.bzrdir.root_transport, to_transport])
1391
except errors.NoSuchRevision:
1392
to_transport.delete_tree('.')
1393
msg = gettext("The branch {0} has no revision {1}.").format(
1394
from_location, revision)
1395
raise errors.BzrCommandError(msg)
1397
branch = br_from.sprout(to_dir, revision_id=revision_id)
1306
1398
_merge_tags_if_possible(br_from, branch)
1307
1399
# If the source branch is stacked, the new branch may
1308
1400
# be stacked whether we asked for that explicitly or not.
1309
1401
# We therefore need a try/except here and not just 'if stacked:'
1311
note('Created new stacked branch referring to %s.' %
1403
note(gettext('Created new stacked branch referring to %s.') %
1312
1404
branch.get_stacked_on_url())
1313
1405
except (errors.NotStacked, errors.UnstackableBranchFormat,
1314
1406
errors.UnstackableRepositoryFormat), e:
1315
note('Branched %d revision(s).' % branch.revno())
1407
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1317
1409
# Bind to the parent
1318
1410
parent_branch = Branch.open(from_location)
1319
1411
branch.bind(parent_branch)
1320
note('New branch bound to %s' % from_location)
1412
note(gettext('New branch bound to %s') % from_location)
1322
1414
# Switch to the new branch
1323
1415
wt, _ = WorkingTree.open_containing('.')
1324
1416
_mod_switch.switch(wt.bzrdir, branch)
1325
note('Switched to branch: %s',
1417
note(gettext('Switched to branch: %s'),
1326
1418
urlutils.unescape_for_display(branch.base, 'utf-8'))
1421
class cmd_branches(Command):
1422
__doc__ = """List the branches available at the current location.
1424
This command will print the names of all the branches at the current
1428
takes_args = ['location?']
1430
Option('recursive', short_name='R',
1431
help='Recursively scan for branches rather than '
1432
'just looking in the specified location.')]
1434
def run(self, location=".", recursive=False):
1436
t = transport.get_transport(location)
1437
if not t.listable():
1438
raise errors.BzrCommandError(
1439
"Can't scan this type of location.")
1440
for b in controldir.ControlDir.find_branches(t):
1441
self.outf.write("%s\n" % urlutils.unescape_for_display(
1442
urlutils.relative_url(t.base, b.base),
1443
self.outf.encoding).rstrip("/"))
1445
dir = controldir.ControlDir.open_containing(location)[0]
1447
active_branch = dir.open_branch(name=None)
1448
except errors.NotBranchError:
1449
active_branch = None
1450
branches = dir.get_branches()
1452
for name, branch in branches.iteritems():
1455
active = (active_branch is not None and
1456
active_branch.base == branch.base)
1457
names[name] = active
1458
# Only mention the current branch explicitly if it's not
1459
# one of the colocated branches
1460
if not any(names.values()) and active_branch is not None:
1461
self.outf.write("* %s\n" % gettext("(default)"))
1462
for name in sorted(names.keys()):
1463
active = names[name]
1468
self.outf.write("%s %s\n" % (
1469
prefix, name.encode(self.outf.encoding)))
1329
1472
class cmd_checkout(Command):
1330
1473
__doc__ = """Create a new checkout of an existing branch.
1433
1576
class cmd_update(Command):
1434
__doc__ = """Update a tree to have the latest code committed to its branch.
1436
This will perform a merge into the working tree, and may generate
1437
conflicts. If you have any local changes, you will still
1438
need to commit them after the update for the update to be complete.
1440
If you want to discard your local changes, you can just do a
1441
'bzr revert' instead of 'bzr commit' after the update.
1443
If you want to restore a file that has been removed locally, use
1444
'bzr revert' instead of 'bzr update'.
1446
If the tree's branch is bound to a master branch, it will also update
1577
__doc__ = """Update a working tree to a new revision.
1579
This will perform a merge of the destination revision (the tip of the
1580
branch, or the specified revision) into the working tree, and then make
1581
that revision the basis revision for the working tree.
1583
You can use this to visit an older revision, or to update a working tree
1584
that is out of date from its branch.
1586
If there are any uncommitted changes in the tree, they will be carried
1587
across and remain as uncommitted changes after the update. To discard
1588
these changes, use 'bzr revert'. The uncommitted changes may conflict
1589
with the changes brought in by the change in basis revision.
1591
If the tree's branch is bound to a master branch, bzr will also update
1447
1592
the branch from the master.
1594
You cannot update just a single file or directory, because each Bazaar
1595
working tree has just a single basis revision. If you want to restore a
1596
file that has been removed locally, use 'bzr revert' instead of 'bzr
1597
update'. If you want to restore a file to its state in a previous
1598
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1599
out the old content of that file to a new location.
1601
The 'dir' argument, if given, must be the location of the root of a
1602
working tree to update. By default, the working tree that contains the
1603
current working directory is used.
1450
1606
_see_also = ['pull', 'working-trees', 'status-flags']
1504
1668
old_tip=old_tip,
1505
1669
show_base=show_base)
1506
1670
except errors.NoSuchRevision, e:
1507
raise errors.BzrCommandError(
1671
raise errors.BzrCommandError(gettext(
1508
1672
"branch has no revision %s\n"
1509
1673
"bzr update --revision only works"
1510
" for a revision in the branch history"
1674
" for a revision in the branch history")
1511
1675
% (e.revision))
1512
1676
revno = tree.branch.revision_id_to_dotted_revno(
1513
1677
_mod_revision.ensure_null(tree.last_revision()))
1514
note('Updated to revision %s of branch %s' %
1515
('.'.join(map(str, revno)), branch_location))
1678
note(gettext('Updated to revision {0} of branch {1}').format(
1679
'.'.join(map(str, revno)), branch_location))
1516
1680
parent_ids = tree.get_parent_ids()
1517
1681
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1518
note('Your local commits will now show as pending merges with '
1519
"'bzr status', and can be committed with 'bzr commit'.")
1682
note(gettext('Your local commits will now show as pending merges with '
1683
"'bzr status', and can be committed with 'bzr commit'."))
1520
1684
if conflicts != 0:
1908
2081
def run(self, location, format=None, no_trees=False):
1909
2082
if format is None:
1910
format = bzrdir.format_registry.make_bzrdir('default')
2083
format = controldir.format_registry.make_bzrdir('default')
1912
2085
if location is None:
1915
2088
to_transport = transport.get_transport(location)
1916
to_transport.ensure_base()
1918
newdir = format.initialize_on_transport(to_transport)
1919
repo = newdir.create_repository(shared=True)
1920
repo.set_make_working_trees(not no_trees)
2090
(repo, newdir, require_stacking, repository_policy) = (
2091
format.initialize_on_transport_ex(to_transport,
2092
create_prefix=True, make_working_trees=not no_trees,
2093
shared_repo=True, force_new_repo=True,
2094
use_existing_dir=True,
2095
repo_format_name=format.repository_format.get_format_string()))
1921
2096
if not is_quiet():
1922
2097
from bzrlib.info import show_bzrdir_info
1923
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2098
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1926
2101
class cmd_diff(Command):
2384
2563
Option('show-diff',
2385
2564
short_name='p',
2386
2565
help='Show changes made in each revision as a patch.'),
2387
Option('include-merges',
2566
Option('include-merged',
2388
2567
help='Show merged revisions like --levels 0 does.'),
2568
Option('include-merges', hidden=True,
2569
help='Historical alias for --include-merged.'),
2570
Option('omit-merges',
2571
help='Do not report commits with more than one parent.'),
2389
2572
Option('exclude-common-ancestry',
2390
2573
help='Display only the revisions that are not part'
2391
' of both ancestries (require -rX..Y)'
2574
' of both ancestries (require -rX..Y).'
2576
Option('signatures',
2577
help='Show digital signature validity.'),
2580
help='Show revisions whose properties match this '
2583
ListOption('match-message',
2584
help='Show revisions whose message matches this '
2587
ListOption('match-committer',
2588
help='Show revisions whose committer matches this '
2591
ListOption('match-author',
2592
help='Show revisions whose authors match this '
2595
ListOption('match-bugs',
2596
help='Show revisions whose bugs match this '
2394
2600
encoding_type = 'replace'
2415
2629
_get_info_for_log_files,
2417
2631
direction = (forward and 'forward') or 'reverse'
2632
if symbol_versioning.deprecated_passed(include_merges):
2633
ui.ui_factory.show_user_warning(
2634
'deprecated_command_option',
2635
deprecated_name='--include-merges',
2636
recommended_name='--include-merged',
2637
deprecated_in_version='2.5',
2638
command=self.invoked_as)
2639
if include_merged is None:
2640
include_merged = include_merges
2642
raise errors.BzrCommandError(gettext(
2643
'{0} and {1} are mutually exclusive').format(
2644
'--include-merges', '--include-merged'))
2645
if include_merged is None:
2646
include_merged = False
2418
2647
if (exclude_common_ancestry
2419
2648
and (revision is None or len(revision) != 2)):
2420
raise errors.BzrCommandError(
2421
'--exclude-common-ancestry requires -r with two revisions')
2649
raise errors.BzrCommandError(gettext(
2650
'--exclude-common-ancestry requires -r with two revisions'))
2423
2652
if levels is None:
2426
raise errors.BzrCommandError(
2427
'--levels and --include-merges are mutually exclusive')
2655
raise errors.BzrCommandError(gettext(
2656
'{0} and {1} are mutually exclusive').format(
2657
'--levels', '--include-merged'))
2429
2659
if change is not None:
2430
2660
if len(change) > 1:
2431
2661
raise errors.RangeInChangeOption()
2432
2662
if revision is not None:
2433
raise errors.BzrCommandError(
2434
'--revision and --change are mutually exclusive')
2663
raise errors.BzrCommandError(gettext(
2664
'{0} and {1} are mutually exclusive').format(
2665
'--revision', '--change'))
2436
2667
revision = change
2822
3073
self.outf.write("%s\n" % pattern)
2824
3075
if not name_pattern_list:
2825
raise errors.BzrCommandError("ignore requires at least one "
2826
"NAME_PATTERN or --default-rules.")
3076
raise errors.BzrCommandError(gettext("ignore requires at least one "
3077
"NAME_PATTERN or --default-rules."))
2827
3078
name_pattern_list = [globbing.normalize_pattern(p)
2828
3079
for p in name_pattern_list]
2829
3080
bad_patterns = ''
3081
bad_patterns_count = 0
2830
3082
for p in name_pattern_list:
2831
3083
if not globbing.Globster.is_pattern_valid(p):
3084
bad_patterns_count += 1
2832
3085
bad_patterns += ('\n %s' % p)
2833
3086
if bad_patterns:
2834
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
3087
msg = (ngettext('Invalid ignore pattern found. %s',
3088
'Invalid ignore patterns found. %s',
3089
bad_patterns_count) % bad_patterns)
2835
3090
ui.ui_factory.show_error(msg)
2836
3091
raise errors.InvalidPattern('')
2837
3092
for name_pattern in name_pattern_list:
2838
3093
if (name_pattern[0] == '/' or
2839
3094
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2840
raise errors.BzrCommandError(
2841
"NAME_PATTERN should not be an absolute path")
3095
raise errors.BzrCommandError(gettext(
3096
"NAME_PATTERN should not be an absolute path"))
2842
3097
tree, relpath = WorkingTree.open_containing(directory)
2843
3098
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2844
3099
ignored = globbing.Globster(name_pattern_list)
2948
3203
Option('per-file-timestamps',
2949
3204
help='Set modification time of files to that of the last '
2950
3205
'revision in which it was changed.'),
3206
Option('uncommitted',
3207
help='Export the working tree contents rather than that of the '
2952
3210
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2953
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3211
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2954
3213
from bzrlib.export import export
2956
3215
if branch_or_subdir is None:
2957
tree = WorkingTree.open_containing(directory)[0]
3216
branch_or_subdir = directory
3218
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3220
if tree is not None:
3221
self.add_cleanup(tree.lock_read().unlock)
3225
raise errors.BzrCommandError(
3226
gettext("--uncommitted requires a working tree"))
2961
b, subdir = Branch.open_containing(branch_or_subdir)
2964
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3229
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2966
export(rev_tree, dest, format, root, subdir, filtered=filters,
3231
export(export_tree, dest, format, root, subdir, filtered=filters,
2967
3232
per_file_timestamps=per_file_timestamps)
2968
3233
except errors.NoSuchExportFormat, e:
2969
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3234
raise errors.BzrCommandError(
3235
gettext('Unsupported export format: %s') % e.format)
2972
3238
class cmd_cat(Command):
3010
3276
old_file_id = rev_tree.path2id(relpath)
3278
# TODO: Split out this code to something that generically finds the
3279
# best id for a path across one or more trees; it's like
3280
# find_ids_across_trees but restricted to find just one. -- mbp
3012
3282
if name_from_revision:
3013
3283
# Try in revision if requested
3014
3284
if old_file_id is None:
3015
raise errors.BzrCommandError(
3016
"%r is not present in revision %s" % (
3285
raise errors.BzrCommandError(gettext(
3286
"{0!r} is not present in revision {1}").format(
3017
3287
filename, rev_tree.get_revision_id()))
3019
content = rev_tree.get_file_text(old_file_id)
3289
actual_file_id = old_file_id
3021
3291
cur_file_id = tree.path2id(relpath)
3023
if cur_file_id is not None:
3024
# Then try with the actual file id
3026
content = rev_tree.get_file_text(cur_file_id)
3028
except errors.NoSuchId:
3029
# The actual file id didn't exist at that time
3031
if not found and old_file_id is not None:
3032
# Finally try with the old file id
3033
content = rev_tree.get_file_text(old_file_id)
3036
# Can't be found anywhere
3037
raise errors.BzrCommandError(
3038
"%r is not present in revision %s" % (
3292
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3293
actual_file_id = cur_file_id
3294
elif old_file_id is not None:
3295
actual_file_id = old_file_id
3297
raise errors.BzrCommandError(gettext(
3298
"{0!r} is not present in revision {1}").format(
3039
3299
filename, rev_tree.get_revision_id()))
3041
from bzrlib.filters import (
3042
ContentFilterContext,
3043
filtered_output_bytes,
3045
filters = rev_tree._content_filter_stack(relpath)
3046
chunks = content.splitlines(True)
3047
content = filtered_output_bytes(chunks, filters,
3048
ContentFilterContext(relpath, rev_tree))
3050
self.outf.writelines(content)
3301
from bzrlib.filter_tree import ContentFilterTree
3302
filter_tree = ContentFilterTree(rev_tree,
3303
rev_tree._content_filter_stack)
3304
content = filter_tree.get_file_text(actual_file_id)
3053
self.outf.write(content)
3306
content = rev_tree.get_file_text(actual_file_id)
3308
self.outf.write(content)
3056
3311
class cmd_local_time_offset(Command):
3163
3418
aliases = ['ci', 'checkin']
3165
3420
def _iter_bug_fix_urls(self, fixes, branch):
3421
default_bugtracker = None
3166
3422
# Configure the properties for bug fixing attributes.
3167
3423
for fixed_bug in fixes:
3168
3424
tokens = fixed_bug.split(':')
3169
if len(tokens) != 2:
3170
raise errors.BzrCommandError(
3425
if len(tokens) == 1:
3426
if default_bugtracker is None:
3427
branch_config = branch.get_config()
3428
default_bugtracker = branch_config.get_user_option(
3430
if default_bugtracker is None:
3431
raise errors.BzrCommandError(gettext(
3432
"No tracker specified for bug %s. Use the form "
3433
"'tracker:id' or specify a default bug tracker "
3434
"using the `bugtracker` option.\nSee "
3435
"\"bzr help bugs\" for more information on this "
3436
"feature. Commit refused.") % fixed_bug)
3437
tag = default_bugtracker
3439
elif len(tokens) != 2:
3440
raise errors.BzrCommandError(gettext(
3171
3441
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3172
3442
"See \"bzr help bugs\" for more information on this "
3173
"feature.\nCommit refused." % fixed_bug)
3174
tag, bug_id = tokens
3443
"feature.\nCommit refused.") % fixed_bug)
3445
tag, bug_id = tokens
3176
3447
yield bugtracker.get_bug_url(tag, branch, bug_id)
3177
3448
except errors.UnknownBugTrackerAbbreviation:
3178
raise errors.BzrCommandError(
3179
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3449
raise errors.BzrCommandError(gettext(
3450
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3180
3451
except errors.MalformedBugIdentifier, e:
3181
raise errors.BzrCommandError(
3182
"%s\nCommit refused." % (str(e),))
3452
raise errors.BzrCommandError(gettext(
3453
"%s\nCommit refused.") % (str(e),))
3184
3455
def run(self, message=None, file=None, verbose=False, selected_list=None,
3185
3456
unchanged=False, strict=False, local=False, fixes=None,
3265
3537
# make_commit_message_template_encoded returns user encoding.
3266
3538
# We probably want to be using edit_commit_message instead to
3268
start_message = generate_commit_message_template(commit_obj)
3269
my_message = edit_commit_message_encoded(text,
3270
start_message=start_message)
3271
if my_message is None:
3272
raise errors.BzrCommandError("please specify a commit"
3273
" message with either --message or --file")
3274
if my_message == "":
3275
raise errors.BzrCommandError("empty commit message specified")
3540
my_message = set_commit_message(commit_obj)
3541
if my_message is None:
3542
start_message = generate_commit_message_template(commit_obj)
3543
my_message = edit_commit_message_encoded(text,
3544
start_message=start_message)
3545
if my_message is None:
3546
raise errors.BzrCommandError(gettext("please specify a commit"
3547
" message with either --message or --file"))
3548
if my_message == "":
3549
raise errors.BzrCommandError(gettext("Empty commit message specified."
3550
" Please specify a commit message with either"
3551
" --message or --file or leave a blank message"
3552
" with --message \"\"."))
3276
3553
return my_message
3278
3555
# The API permits a commit with a filter of [] to mean 'select nothing'
3289
3566
exclude=tree.safe_relpath_files(exclude),
3291
3568
except PointlessCommit:
3292
raise errors.BzrCommandError("No changes to commit."
3569
raise errors.BzrCommandError(gettext("No changes to commit."
3293
3570
" Please 'bzr add' the files you want to commit, or use"
3294
" --unchanged to force an empty commit.")
3571
" --unchanged to force an empty commit."))
3295
3572
except ConflictsInTree:
3296
raise errors.BzrCommandError('Conflicts detected in working '
3573
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3297
3574
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3299
3576
except StrictCommitFailed:
3300
raise errors.BzrCommandError("Commit refused because there are"
3301
" unknown files in the working tree.")
3577
raise errors.BzrCommandError(gettext("Commit refused because there are"
3578
" unknown files in the working tree."))
3302
3579
except errors.BoundBranchOutOfDate, e:
3303
e.extra_help = ("\n"
3580
e.extra_help = (gettext("\n"
3304
3581
'To commit to master branch, run update and then commit.\n'
3305
3582
'You can also pass --local to commit to continue working '
4020
4323
if merger.interesting_files:
4021
4324
if not merger.other_tree.has_filename(
4022
4325
merger.interesting_files[0]):
4023
note("merger: " + str(merger))
4326
note(gettext("merger: ") + str(merger))
4024
4327
raise errors.PathsDoNotExist([location])
4025
note('Nothing to do.')
4328
note(gettext('Nothing to do.'))
4027
4330
if pull and not preview:
4028
4331
if merger.interesting_files is not None:
4029
raise errors.BzrCommandError('Cannot pull individual files')
4332
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4030
4333
if (merger.base_rev_id == tree.last_revision()):
4031
4334
result = tree.pull(merger.other_branch, False,
4032
4335
merger.other_rev_id)
4033
4336
result.report(self.outf)
4035
4338
if merger.this_basis is None:
4036
raise errors.BzrCommandError(
4339
raise errors.BzrCommandError(gettext(
4037
4340
"This branch has no commits."
4038
" (perhaps you would prefer 'bzr pull')")
4341
" (perhaps you would prefer 'bzr pull')"))
4040
4343
return self._do_preview(merger)
4041
4344
elif interactive:
4499
4804
theirs_only=False,
4500
4805
log_format=None, long=False, short=False, line=False,
4501
4806
show_ids=False, verbose=False, this=False, other=False,
4502
include_merges=False, revision=None, my_revision=None,
4807
include_merged=None, revision=None, my_revision=None,
4809
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4504
4810
from bzrlib.missing import find_unmerged, iter_log_revisions
4505
4811
def message(s):
4506
4812
if not is_quiet():
4507
4813
self.outf.write(s)
4815
if symbol_versioning.deprecated_passed(include_merges):
4816
ui.ui_factory.show_user_warning(
4817
'deprecated_command_option',
4818
deprecated_name='--include-merges',
4819
recommended_name='--include-merged',
4820
deprecated_in_version='2.5',
4821
command=self.invoked_as)
4822
if include_merged is None:
4823
include_merged = include_merges
4825
raise errors.BzrCommandError(gettext(
4826
'{0} and {1} are mutually exclusive').format(
4827
'--include-merges', '--include-merged'))
4828
if include_merged is None:
4829
include_merged = False
4510
4831
mine_only = this
4840
5165
location = b.get_old_bound_location()
4841
5166
except errors.UpgradeRequired:
4842
raise errors.BzrCommandError('No location supplied. '
4843
'This format does not remember old locations.')
5167
raise errors.BzrCommandError(gettext('No location supplied. '
5168
'This format does not remember old locations.'))
4845
5170
if location is None:
4846
5171
if b.get_bound_location() is not None:
4847
raise errors.BzrCommandError('Branch is already bound')
5172
raise errors.BzrCommandError(gettext('Branch is already bound'))
4849
raise errors.BzrCommandError('No location supplied '
4850
'and no previous location known')
5174
raise errors.BzrCommandError(gettext('No location supplied '
5175
'and no previous location known'))
4851
5176
b_other = Branch.open(location)
4853
5178
b.bind(b_other)
4854
5179
except errors.DivergedBranches:
4855
raise errors.BzrCommandError('These branches have diverged.'
4856
' Try merging, and then bind again.')
5180
raise errors.BzrCommandError(gettext('These branches have diverged.'
5181
' Try merging, and then bind again.'))
4857
5182
if b.get_config().has_explicit_nickname():
4858
5183
b.nick = b_other.nick
4925
5251
self.add_cleanup(tree.lock_write().unlock)
4927
5253
self.add_cleanup(b.lock_write().unlock)
4928
return self._run(b, tree, dry_run, verbose, revision, force, local=local)
5254
return self._run(b, tree, dry_run, verbose, revision, force,
4930
def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
5257
def _run(self, b, tree, dry_run, verbose, revision, force, local,
4931
5259
from bzrlib.log import log_formatter, show_log
4932
5260
from bzrlib.uncommit import uncommit
4963
5291
end_revision=last_revno)
4966
self.outf.write('Dry-run, pretending to remove'
4967
' the above revisions.\n')
5294
self.outf.write(gettext('Dry-run, pretending to remove'
5295
' the above revisions.\n'))
4969
self.outf.write('The above revision(s) will be removed.\n')
5297
self.outf.write(gettext('The above revision(s) will be removed.\n'))
4972
5300
if not ui.ui_factory.confirm_action(
4973
u'Uncommit these revisions',
5301
gettext(u'Uncommit these revisions'),
4974
5302
'bzrlib.builtins.uncommit',
4976
self.outf.write('Canceled\n')
5304
self.outf.write(gettext('Canceled\n'))
4979
5307
mutter('Uncommitting from {%s} to {%s}',
4980
5308
last_rev_id, rev_id)
4981
5309
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4982
revno=revno, local=local)
4983
self.outf.write('You can restore the old tip by running:\n'
4984
' bzr pull . -r revid:%s\n' % last_rev_id)
5310
revno=revno, local=local, keep_tags=keep_tags)
5311
self.outf.write(gettext('You can restore the old tip by running:\n'
5312
' bzr pull . -r revid:%s\n') % last_rev_id)
4987
5315
class cmd_break_lock(Command):
5093
5423
return host, port
5095
5425
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5426
protocol=None, client_timeout=None):
5097
5427
from bzrlib import transport
5098
5428
if directory is None:
5099
5429
directory = os.getcwd()
5100
5430
if protocol is None:
5101
5431
protocol = transport.transport_server_registry.get()
5102
5432
host, port = self.get_host_and_port(port)
5103
url = urlutils.local_path_to_url(directory)
5433
url = transport.location_to_url(directory)
5104
5434
if not allow_writes:
5105
5435
url = 'readonly+' + url
5106
t = transport.get_transport(url)
5107
protocol(t, host, port, inet)
5436
t = transport.get_transport_from_url(url)
5438
protocol(t, host, port, inet, client_timeout)
5439
except TypeError, e:
5440
# We use symbol_versioning.deprecated_in just so that people
5441
# grepping can find it here.
5442
# symbol_versioning.deprecated_in((2, 5, 0))
5443
symbol_versioning.warn(
5444
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5445
'Most likely it needs to be updated to support a'
5446
' "timeout" parameter (added in bzr 2.5.0)'
5447
% (e, protocol.__module__, protocol),
5449
protocol(t, host, port, inet)
5110
5452
class cmd_join(Command):
5522
5864
self.add_cleanup(branch.lock_write().unlock)
5524
5866
if tag_name is None:
5525
raise errors.BzrCommandError("No tag specified to delete.")
5867
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5526
5868
branch.tags.delete_tag(tag_name)
5527
note('Deleted tag %s.' % tag_name)
5869
note(gettext('Deleted tag %s.') % tag_name)
5530
5872
if len(revision) != 1:
5531
raise errors.BzrCommandError(
5873
raise errors.BzrCommandError(gettext(
5532
5874
"Tags can only be placed on a single revision, "
5534
5876
revision_id = revision[0].as_revision_id(branch)
5536
5878
revision_id = branch.last_revision()
5537
5879
if tag_name is None:
5538
5880
tag_name = branch.automatic_tag_name(revision_id)
5539
5881
if tag_name is None:
5540
raise errors.BzrCommandError(
5541
"Please specify a tag name.")
5542
if (not force) and branch.tags.has_tag(tag_name):
5882
raise errors.BzrCommandError(gettext(
5883
"Please specify a tag name."))
5885
existing_target = branch.tags.lookup_tag(tag_name)
5886
except errors.NoSuchTag:
5887
existing_target = None
5888
if not force and existing_target not in (None, revision_id):
5543
5889
raise errors.TagAlreadyExists(tag_name)
5544
branch.tags.set_tag(tag_name, revision_id)
5545
note('Created tag %s.' % tag_name)
5890
if existing_target == revision_id:
5891
note(gettext('Tag %s already exists for that revision.') % tag_name)
5893
branch.tags.set_tag(tag_name, revision_id)
5894
if existing_target is None:
5895
note(gettext('Created tag %s.') % tag_name)
5897
note(gettext('Updated tag %s.') % tag_name)
5548
5900
class cmd_tags(Command):
5599
5949
for tag, revspec in tags:
5600
5950
self.outf.write('%-20s %s\n' % (tag, revspec))
5952
def _tags_for_range(self, branch, revision):
5954
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5955
revid1, revid2 = rev1.rev_id, rev2.rev_id
5956
# _get_revision_range will always set revid2 if it's not specified.
5957
# If revid1 is None, it means we want to start from the branch
5958
# origin which is always a valid ancestor. If revid1 == revid2, the
5959
# ancestry check is useless.
5960
if revid1 and revid1 != revid2:
5961
# FIXME: We really want to use the same graph than
5962
# branch.iter_merge_sorted_revisions below, but this is not
5963
# easily available -- vila 2011-09-23
5964
if branch.repository.get_graph().is_ancestor(revid2, revid1):
5965
# We don't want to output anything in this case...
5967
# only show revisions between revid1 and revid2 (inclusive)
5968
tagged_revids = branch.tags.get_reverse_tag_dict()
5970
for r in branch.iter_merge_sorted_revisions(
5971
start_revision_id=revid2, stop_revision_id=revid1,
5972
stop_rule='include'):
5973
revid_tags = tagged_revids.get(r[0], None)
5975
found.extend([(tag, r[0]) for tag in revid_tags])
5603
5979
class cmd_reconfigure(Command):
5604
5980
__doc__ = """Reconfigure the type of a bzr directory.
5618
5994
takes_args = ['location?']
5619
5995
takes_options = [
5620
5996
RegistryOption.from_kwargs(
5622
title='Target type',
5623
help='The type to reconfigure the directory to.',
5999
help='The relation between branch and tree.',
5624
6000
value_switches=True, enum_switch=False,
5625
6001
branch='Reconfigure to be an unbound branch with no working tree.',
5626
6002
tree='Reconfigure to be an unbound branch with a working tree.',
5627
6003
checkout='Reconfigure to be a bound branch with a working tree.',
5628
6004
lightweight_checkout='Reconfigure to be a lightweight'
5629
6005
' checkout (with no local history).',
6007
RegistryOption.from_kwargs(
6009
title='Repository type',
6010
help='Location fo the repository.',
6011
value_switches=True, enum_switch=False,
5630
6012
standalone='Reconfigure to be a standalone branch '
5631
6013
'(i.e. stop using shared repository).',
5632
6014
use_shared='Reconfigure to use a shared repository.',
6016
RegistryOption.from_kwargs(
6018
title='Trees in Repository',
6019
help='Whether new branches in the repository have trees.',
6020
value_switches=True, enum_switch=False,
5633
6021
with_trees='Reconfigure repository to create '
5634
6022
'working trees on branches by default.',
5635
6023
with_no_trees='Reconfigure repository to not create '
5662
6050
# At the moment you can use --stacked-on and a different
5663
6051
# reconfiguration shape at the same time; there seems no good reason
5665
if target_type is None:
6053
if (tree_type is None and
6054
repository_type is None and
6055
repository_trees is None):
5666
6056
if stacked_on or unstacked:
5669
raise errors.BzrCommandError('No target configuration '
5671
elif target_type == 'branch':
6059
raise errors.BzrCommandError(gettext('No target configuration '
6061
reconfiguration = None
6062
if tree_type == 'branch':
5672
6063
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5673
elif target_type == 'tree':
6064
elif tree_type == 'tree':
5674
6065
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5675
elif target_type == 'checkout':
6066
elif tree_type == 'checkout':
5676
6067
reconfiguration = reconfigure.Reconfigure.to_checkout(
5677
6068
directory, bind_to)
5678
elif target_type == 'lightweight-checkout':
6069
elif tree_type == 'lightweight-checkout':
5679
6070
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5680
6071
directory, bind_to)
5681
elif target_type == 'use-shared':
6073
reconfiguration.apply(force)
6074
reconfiguration = None
6075
if repository_type == 'use-shared':
5682
6076
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5683
elif target_type == 'standalone':
6077
elif repository_type == 'standalone':
5684
6078
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5685
elif target_type == 'with-trees':
6080
reconfiguration.apply(force)
6081
reconfiguration = None
6082
if repository_trees == 'with-trees':
5686
6083
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5687
6084
directory, True)
5688
elif target_type == 'with-no-trees':
6085
elif repository_trees == 'with-no-trees':
5689
6086
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5690
6087
directory, False)
5691
reconfiguration.apply(force)
6089
reconfiguration.apply(force)
6090
reconfiguration = None
5694
6093
class cmd_switch(Command):
5743
6142
had_explicit_nick = False
5744
6143
if create_branch:
5745
6144
if branch is None:
5746
raise errors.BzrCommandError('cannot create branch without'
6145
raise errors.BzrCommandError(gettext('cannot create branch without'
5748
6147
to_location = directory_service.directories.dereference(
5750
6149
if '/' not in to_location and '\\' not in to_location:
5751
6150
# This path is meant to be relative to the existing branch
5752
6151
this_url = self._get_branch_location(control_dir)
5753
to_location = urlutils.join(this_url, '..', to_location)
6152
# Perhaps the target control dir supports colocated branches?
6154
root = controldir.ControlDir.open(this_url,
6155
possible_transports=[control_dir.user_transport])
6156
except errors.NotBranchError:
6159
colocated = root._format.colocated_branches
6161
to_location = urlutils.join_segment_parameters(this_url,
6162
{"branch": urlutils.escape(to_location)})
6164
to_location = urlutils.join(
6165
this_url, '..', urlutils.escape(to_location))
5754
6166
to_branch = branch.bzrdir.sprout(to_location,
5755
6167
possible_transports=[branch.bzrdir.root_transport],
5756
6168
source_branch=branch).open_branch()
6170
# Perhaps it's a colocated branch?
5759
to_branch = Branch.open(to_location)
5760
except errors.NotBranchError:
5761
this_url = self._get_branch_location(control_dir)
5762
to_branch = Branch.open(
5763
urlutils.join(this_url, '..', to_location))
6172
to_branch = control_dir.open_branch(to_location)
6173
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6175
to_branch = Branch.open(to_location)
6176
except errors.NotBranchError:
6177
this_url = self._get_branch_location(control_dir)
6178
to_branch = Branch.open(
6180
this_url, '..', urlutils.escape(to_location)))
5764
6181
if revision is not None:
5765
6182
revision = revision.as_revision_id(to_branch)
5766
6183
switch.switch(control_dir, to_branch, force, revision_id=revision)
5767
6184
if had_explicit_nick:
5768
6185
branch = control_dir.open_branch() #get the new branch!
5769
6186
branch.nick = to_branch.nick
5770
note('Switched to branch: %s',
6187
note(gettext('Switched to branch: %s'),
5771
6188
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5773
6190
def _get_branch_location(self, control_dir):
5882
6299
name = current_view
5885
raise errors.BzrCommandError(
5886
"Both --delete and a file list specified")
6302
raise errors.BzrCommandError(gettext(
6303
"Both --delete and a file list specified"))
5888
raise errors.BzrCommandError(
5889
"Both --delete and --switch specified")
6305
raise errors.BzrCommandError(gettext(
6306
"Both --delete and --switch specified"))
5891
6308
tree.views.set_view_info(None, {})
5892
self.outf.write("Deleted all views.\n")
6309
self.outf.write(gettext("Deleted all views.\n"))
5893
6310
elif name is None:
5894
raise errors.BzrCommandError("No current view to delete")
6311
raise errors.BzrCommandError(gettext("No current view to delete"))
5896
6313
tree.views.delete_view(name)
5897
self.outf.write("Deleted '%s' view.\n" % name)
6314
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5900
raise errors.BzrCommandError(
5901
"Both --switch and a file list specified")
6317
raise errors.BzrCommandError(gettext(
6318
"Both --switch and a file list specified"))
5903
raise errors.BzrCommandError(
5904
"Both --switch and --all specified")
6320
raise errors.BzrCommandError(gettext(
6321
"Both --switch and --all specified"))
5905
6322
elif switch == 'off':
5906
6323
if current_view is None:
5907
raise errors.BzrCommandError("No current view to disable")
6324
raise errors.BzrCommandError(gettext("No current view to disable"))
5908
6325
tree.views.set_view_info(None, view_dict)
5909
self.outf.write("Disabled '%s' view.\n" % (current_view))
6326
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5911
6328
tree.views.set_view_info(switch, view_dict)
5912
6329
view_str = views.view_display_str(tree.views.lookup_view())
5913
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6330
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5916
self.outf.write('Views defined:\n')
6333
self.outf.write(gettext('Views defined:\n'))
5917
6334
for view in sorted(view_dict):
5918
6335
if view == current_view:
5922
6339
view_str = views.view_display_str(view_dict[view])
5923
6340
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5925
self.outf.write('No views defined.\n')
6342
self.outf.write(gettext('No views defined.\n'))
5926
6343
elif file_list:
5927
6344
if name is None:
5928
6345
# No name given and no current view set
5930
6347
elif name == 'off':
5931
raise errors.BzrCommandError(
5932
"Cannot change the 'off' pseudo view")
6348
raise errors.BzrCommandError(gettext(
6349
"Cannot change the 'off' pseudo view"))
5933
6350
tree.views.set_view(name, sorted(file_list))
5934
6351
view_str = views.view_display_str(tree.views.lookup_view())
5935
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6352
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5937
6354
# list the files
5938
6355
if name is None:
5939
6356
# No name given and no current view set
5940
self.outf.write('No current view.\n')
6357
self.outf.write(gettext('No current view.\n'))
5942
6359
view_str = views.view_display_str(tree.views.lookup_view(name))
5943
self.outf.write("'%s' view is: %s\n" % (name, view_str))
6360
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5946
6363
class cmd_hooks(Command):