86
def _get_branch_location(control_dir, possible_transports=None):
87
"""Return location of branch for this control dir."""
89
this_branch = control_dir.open_branch(
90
possible_transports=possible_transports)
91
# This may be a heavy checkout, where we want the master branch
92
master_location = this_branch.get_bound_location()
93
if master_location is not None:
94
return master_location
95
# If not, use a local sibling
96
return this_branch.base
97
except errors.NotBranchError:
98
format = control_dir.find_branch_format()
99
if getattr(format, 'get_reference', None) is not None:
100
return format.get_reference(control_dir)
102
return control_dir.root_transport.base
105
def _is_colocated(control_dir, possible_transports=None):
106
"""Check if the branch in control_dir is colocated.
108
:param control_dir: Control directory
109
:return: Boolean indicating whether
111
# This path is meant to be relative to the existing branch
112
this_url = _get_branch_location(control_dir,
113
possible_transports=possible_transports)
114
# Perhaps the target control dir supports colocated branches?
116
root = controldir.ControlDir.open(this_url,
117
possible_transports=possible_transports)
118
except errors.NotBranchError:
119
return (False, this_url)
122
wt = control_dir.open_workingtree()
123
except (errors.NoWorkingTree, errors.NotLocalUrl):
124
return (False, this_url)
127
root._format.colocated_branches and
128
control_dir.control_url == root.control_url,
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
"""Lookup the location for a new sibling branch.
135
:param control_dir: Control directory relative to which to look up
137
:param location: Name of the new branch
138
:return: Full location to the new branch
140
location = directory_service.directories.dereference(location)
141
if '/' not in location and '\\' not in location:
142
(colocated, this_url) = _is_colocated(control_dir, possible_transports)
145
return urlutils.join_segment_parameters(this_url,
146
{"branch": urlutils.escape(location)})
148
return urlutils.join(this_url, '..', urlutils.escape(location))
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
"""Lookup sibling branch.
155
:param control_dir: Control directory relative to which to lookup the
157
:param location: Location to look up
158
:return: branch to open
161
# Perhaps it's a colocated branch?
162
return control_dir.open_branch(location,
163
possible_transports=possible_transports)
164
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
166
return Branch.open(location)
167
except errors.NotBranchError:
168
this_url = _get_branch_location(control_dir)
171
this_url, '..', urlutils.escape(location)))
80
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
81
175
def tree_files(file_list, default_branch=u'.', canonicalize=True,
556
649
_see_also = ['info']
557
650
takes_args = ['location?']
558
651
takes_options = [
559
Option('tree', help='Show revno of working tree'),
652
Option('tree', help='Show revno of working tree.'),
563
def run(self, tree=False, location=u'.'):
657
def run(self, tree=False, location=u'.', revision=None):
658
if revision is not None and tree:
659
raise errors.BzrCommandError(gettext("--tree and --revision can "
660
"not be used together"))
566
664
wt = WorkingTree.open_containing(location)[0]
567
665
self.add_cleanup(wt.lock_read().unlock)
568
666
except (errors.NoWorkingTree, errors.NotLocalUrl):
569
667
raise errors.NoWorkingTree(location)
570
669
revid = wt.last_revision()
572
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
573
except errors.NoSuchRevision:
575
revno = ".".join(str(n) for n in revno_t)
577
671
b = Branch.open_containing(location)[0]
578
672
self.add_cleanup(b.lock_read().unlock)
674
if len(revision) != 1:
675
raise errors.BzrCommandError(gettext(
676
"Tags can only be placed on a single revision, "
678
revid = revision[0].as_revision_id(b)
680
revid = b.last_revision()
682
revno_t = b.revision_id_to_dotted_revno(revid)
683
except errors.NoSuchRevision:
685
revno = ".".join(str(n) for n in revno_t)
580
686
self.cleanup_now()
581
self.outf.write(str(revno) + '\n')
687
self.outf.write(revno + '\n')
584
690
class cmd_revision_info(Command):
732
846
takes_args = ['dir+']
850
help='No error if existing, make parent directories as needed.',
733
854
encoding_type = 'replace'
735
def run(self, dir_list):
737
wt, dd = WorkingTree.open_containing(d)
738
base = os.path.dirname(dd)
739
id = wt.path2id(base)
743
self.outf.write('added %s\n' % d)
857
def add_file_with_parents(cls, wt, relpath):
858
if wt.path2id(relpath) is not None:
860
cls.add_file_with_parents(wt, osutils.dirname(relpath))
864
def add_file_single(cls, wt, relpath):
867
def run(self, dir_list, parents=False):
869
add_file = self.add_file_with_parents
871
add_file = self.add_file_single
873
wt, relpath = WorkingTree.open_containing(dir)
878
if e.errno != errno.EEXIST:
745
raise errors.NotVersionedError(path=base)
882
add_file(wt, relpath)
884
self.outf.write(gettext('added %s\n') % dir)
748
887
class cmd_relpath(Command):
855
994
return self.run_auto(names_list, after, dry_run)
857
raise errors.BzrCommandError('--dry-run requires --auto.')
996
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
858
997
if names_list is None:
860
999
if len(names_list) < 2:
861
raise errors.BzrCommandError("missing file argument")
1000
raise errors.BzrCommandError(gettext("missing file argument"))
862
1001
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1002
for file_name in rel_names[0:-1]:
1004
raise errors.BzrCommandError(gettext("can not move root of branch"))
863
1005
self.add_cleanup(tree.lock_tree_write().unlock)
864
1006
self._run(tree, names_list, rel_names, after)
866
1008
def run_auto(self, names_list, after, dry_run):
867
1009
if names_list is not None and len(names_list) > 1:
868
raise errors.BzrCommandError('Only one path may be specified to'
1010
raise errors.BzrCommandError(gettext('Only one path may be specified to'
871
raise errors.BzrCommandError('--after cannot be specified with'
1013
raise errors.BzrCommandError(gettext('--after cannot be specified with'
873
1015
work_tree, file_list = WorkingTree.open_containing_paths(
874
1016
names_list, default_directory='.')
875
1017
self.add_cleanup(work_tree.lock_tree_write().unlock)
1183
1332
# error by the feedback given to them. RBC 20080227.
1184
1333
stacked_on = parent_url
1185
1334
if not stacked_on:
1186
raise errors.BzrCommandError(
1187
"Could not determine branch to refer to.")
1335
raise errors.BzrCommandError(gettext(
1336
"Could not determine branch to refer to."))
1189
1338
# Get the destination location
1190
1339
if location is None:
1191
1340
stored_loc = br_from.get_push_location()
1192
1341
if stored_loc is None:
1193
raise errors.BzrCommandError(
1194
"No push location known or specified.")
1342
parent_loc = br_from.get_parent()
1344
raise errors.BzrCommandError(gettext(
1345
"No push location known or specified. To push to the "
1346
"parent branch (at %s), use 'bzr push :parent'." %
1347
urlutils.unescape_for_display(parent_loc,
1348
self.outf.encoding)))
1350
raise errors.BzrCommandError(gettext(
1351
"No push location known or specified."))
1196
1353
display_url = urlutils.unescape_for_display(stored_loc,
1197
1354
self.outf.encoding)
1198
self.outf.write("Using saved push location: %s\n" % display_url)
1355
note(gettext("Using saved push location: %s") % display_url)
1199
1356
location = stored_loc
1201
1358
_show_push_branch(br_from, revision_id, location, self.outf,
1279
1436
revision_id = br_from.last_revision()
1280
1437
if to_location is None:
1281
to_location = urlutils.derive_to_location(from_location)
1438
to_location = getattr(br_from, "name", None)
1440
to_location = urlutils.derive_to_location(from_location)
1282
1441
to_transport = transport.get_transport(to_location)
1284
1443
to_transport.mkdir('.')
1285
1444
except errors.FileExists:
1286
if not use_existing_dir:
1287
raise errors.BzrCommandError('Target directory "%s" '
1288
'already exists.' % to_location)
1446
to_dir = controldir.ControlDir.open_from_transport(
1448
except errors.NotBranchError:
1449
if not use_existing_dir:
1450
raise errors.BzrCommandError(gettext('Target directory "%s" '
1451
'already exists.') % to_location)
1291
bzrdir.BzrDir.open_from_transport(to_transport)
1456
to_dir.open_branch()
1292
1457
except errors.NotBranchError:
1295
1460
raise errors.AlreadyBranchError(to_location)
1296
1461
except errors.NoSuchFile:
1297
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1462
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1300
# preserve whatever source format we have.
1301
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1302
possible_transports=[to_transport],
1303
accelerator_tree=accelerator_tree,
1304
hardlink=hardlink, stacked=stacked,
1305
force_new_repo=standalone,
1306
create_tree_if_local=not no_tree,
1307
source_branch=br_from)
1308
branch = dir.open_branch()
1309
except errors.NoSuchRevision:
1310
to_transport.delete_tree('.')
1311
msg = "The branch %s has no revision %s." % (from_location,
1313
raise errors.BzrCommandError(msg)
1468
# preserve whatever source format we have.
1469
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1470
possible_transports=[to_transport],
1471
accelerator_tree=accelerator_tree,
1472
hardlink=hardlink, stacked=stacked,
1473
force_new_repo=standalone,
1474
create_tree_if_local=not no_tree,
1475
source_branch=br_from)
1476
branch = to_dir.open_branch(
1477
possible_transports=[
1478
br_from.bzrdir.root_transport, to_transport])
1479
except errors.NoSuchRevision:
1480
to_transport.delete_tree('.')
1481
msg = gettext("The branch {0} has no revision {1}.").format(
1482
from_location, revision)
1483
raise errors.BzrCommandError(msg)
1486
to_repo = to_dir.open_repository()
1487
except errors.NoRepositoryPresent:
1488
to_repo = to_dir.create_repository()
1489
to_repo.fetch(br_from.repository, revision_id=revision_id)
1490
branch = br_from.sprout(to_dir, revision_id=revision_id)
1314
1491
_merge_tags_if_possible(br_from, branch)
1315
1492
# If the source branch is stacked, the new branch may
1316
1493
# be stacked whether we asked for that explicitly or not.
1317
1494
# We therefore need a try/except here and not just 'if stacked:'
1319
note('Created new stacked branch referring to %s.' %
1496
note(gettext('Created new stacked branch referring to %s.') %
1320
1497
branch.get_stacked_on_url())
1321
1498
except (errors.NotStacked, errors.UnstackableBranchFormat,
1322
1499
errors.UnstackableRepositoryFormat), e:
1323
note('Branched %d revision(s).' % branch.revno())
1500
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1325
1502
# Bind to the parent
1326
1503
parent_branch = Branch.open(from_location)
1327
1504
branch.bind(parent_branch)
1328
note('New branch bound to %s' % from_location)
1505
note(gettext('New branch bound to %s') % from_location)
1330
1507
# Switch to the new branch
1331
1508
wt, _ = WorkingTree.open_containing('.')
1332
1509
_mod_switch.switch(wt.bzrdir, branch)
1333
note('Switched to branch: %s',
1510
note(gettext('Switched to branch: %s'),
1334
1511
urlutils.unescape_for_display(branch.base, 'utf-8'))
1514
class cmd_branches(Command):
1515
__doc__ = """List the branches available at the current location.
1517
This command will print the names of all the branches at the current
1521
takes_args = ['location?']
1523
Option('recursive', short_name='R',
1524
help='Recursively scan for branches rather than '
1525
'just looking in the specified location.')]
1527
def run(self, location=".", recursive=False):
1529
t = transport.get_transport(location)
1530
if not t.listable():
1531
raise errors.BzrCommandError(
1532
"Can't scan this type of location.")
1533
for b in controldir.ControlDir.find_branches(t):
1534
self.outf.write("%s\n" % urlutils.unescape_for_display(
1535
urlutils.relative_url(t.base, b.base),
1536
self.outf.encoding).rstrip("/"))
1538
dir = controldir.ControlDir.open_containing(location)[0]
1540
active_branch = dir.open_branch(name="")
1541
except errors.NotBranchError:
1542
active_branch = None
1543
branches = dir.get_branches()
1545
for name, branch in branches.iteritems():
1548
active = (active_branch is not None and
1549
active_branch.base == branch.base)
1550
names[name] = active
1551
# Only mention the current branch explicitly if it's not
1552
# one of the colocated branches
1553
if not any(names.values()) and active_branch is not None:
1554
self.outf.write("* %s\n" % gettext("(default)"))
1555
for name in sorted(names.keys()):
1556
active = names[name]
1561
self.outf.write("%s %s\n" % (
1562
prefix, name.encode(self.outf.encoding)))
1337
1565
class cmd_checkout(Command):
1338
1566
__doc__ = """Create a new checkout of an existing branch.
1441
1669
class cmd_update(Command):
1442
__doc__ = """Update a tree to have the latest code committed to its branch.
1444
This will perform a merge into the working tree, and may generate
1445
conflicts. If you have any local changes, you will still
1446
need to commit them after the update for the update to be complete.
1448
If you want to discard your local changes, you can just do a
1449
'bzr revert' instead of 'bzr commit' after the update.
1451
If you want to restore a file that has been removed locally, use
1452
'bzr revert' instead of 'bzr update'.
1454
If the tree's branch is bound to a master branch, it will also update
1670
__doc__ = """Update a working tree to a new revision.
1672
This will perform a merge of the destination revision (the tip of the
1673
branch, or the specified revision) into the working tree, and then make
1674
that revision the basis revision for the working tree.
1676
You can use this to visit an older revision, or to update a working tree
1677
that is out of date from its branch.
1679
If there are any uncommitted changes in the tree, they will be carried
1680
across and remain as uncommitted changes after the update. To discard
1681
these changes, use 'bzr revert'. The uncommitted changes may conflict
1682
with the changes brought in by the change in basis revision.
1684
If the tree's branch is bound to a master branch, bzr will also update
1455
1685
the branch from the master.
1687
You cannot update just a single file or directory, because each Bazaar
1688
working tree has just a single basis revision. If you want to restore a
1689
file that has been removed locally, use 'bzr revert' instead of 'bzr
1690
update'. If you want to restore a file to its state in a previous
1691
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1692
out the old content of that file to a new location.
1694
The 'dir' argument, if given, must be the location of the root of a
1695
working tree to update. By default, the working tree that contains the
1696
current working directory is used.
1458
1699
_see_also = ['pull', 'working-trees', 'status-flags']
1512
1761
old_tip=old_tip,
1513
1762
show_base=show_base)
1514
1763
except errors.NoSuchRevision, e:
1515
raise errors.BzrCommandError(
1764
raise errors.BzrCommandError(gettext(
1516
1765
"branch has no revision %s\n"
1517
1766
"bzr update --revision only works"
1518
" for a revision in the branch history"
1767
" for a revision in the branch history")
1519
1768
% (e.revision))
1520
1769
revno = tree.branch.revision_id_to_dotted_revno(
1521
1770
_mod_revision.ensure_null(tree.last_revision()))
1522
note('Updated to revision %s of branch %s' %
1523
('.'.join(map(str, revno)), branch_location))
1771
note(gettext('Updated to revision {0} of branch {1}').format(
1772
'.'.join(map(str, revno)), branch_location))
1524
1773
parent_ids = tree.get_parent_ids()
1525
1774
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1526
note('Your local commits will now show as pending merges with '
1527
"'bzr status', and can be committed with 'bzr commit'.")
1775
note(gettext('Your local commits will now show as pending merges with '
1776
"'bzr status', and can be committed with 'bzr commit'."))
1528
1777
if conflicts != 0:
1920
2174
def run(self, location, format=None, no_trees=False):
1921
2175
if format is None:
1922
format = bzrdir.format_registry.make_bzrdir('default')
2176
format = controldir.format_registry.make_bzrdir('default')
1924
2178
if location is None:
1927
2181
to_transport = transport.get_transport(location)
1928
to_transport.ensure_base()
1930
newdir = format.initialize_on_transport(to_transport)
1931
repo = newdir.create_repository(shared=True)
1932
repo.set_make_working_trees(not no_trees)
2183
(repo, newdir, require_stacking, repository_policy) = (
2184
format.initialize_on_transport_ex(to_transport,
2185
create_prefix=True, make_working_trees=not no_trees,
2186
shared_repo=True, force_new_repo=True,
2187
use_existing_dir=True,
2188
repo_format_name=format.repository_format.get_format_string()))
1933
2189
if not is_quiet():
1934
2190
from bzrlib.info import show_bzrdir_info
1935
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2191
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1938
2194
class cmd_diff(Command):
2396
2656
Option('show-diff',
2397
2657
short_name='p',
2398
2658
help='Show changes made in each revision as a patch.'),
2399
Option('include-merges',
2659
Option('include-merged',
2400
2660
help='Show merged revisions like --levels 0 does.'),
2661
Option('include-merges', hidden=True,
2662
help='Historical alias for --include-merged.'),
2663
Option('omit-merges',
2664
help='Do not report commits with more than one parent.'),
2401
2665
Option('exclude-common-ancestry',
2402
2666
help='Display only the revisions that are not part'
2403
' of both ancestries (require -rX..Y)'
2667
' of both ancestries (require -rX..Y).'
2405
2669
Option('signatures',
2406
help='Show digital signature validity'),
2670
help='Show digital signature validity.'),
2673
help='Show revisions whose properties match this '
2676
ListOption('match-message',
2677
help='Show revisions whose message matches this '
2680
ListOption('match-committer',
2681
help='Show revisions whose committer matches this '
2684
ListOption('match-author',
2685
help='Show revisions whose authors match this '
2688
ListOption('match-bugs',
2689
help='Show revisions whose bugs match this '
2408
2693
encoding_type = 'replace'
2430
2722
_get_info_for_log_files,
2432
2724
direction = (forward and 'forward') or 'reverse'
2725
if symbol_versioning.deprecated_passed(include_merges):
2726
ui.ui_factory.show_user_warning(
2727
'deprecated_command_option',
2728
deprecated_name='--include-merges',
2729
recommended_name='--include-merged',
2730
deprecated_in_version='2.5',
2731
command=self.invoked_as)
2732
if include_merged is None:
2733
include_merged = include_merges
2735
raise errors.BzrCommandError(gettext(
2736
'{0} and {1} are mutually exclusive').format(
2737
'--include-merges', '--include-merged'))
2738
if include_merged is None:
2739
include_merged = False
2433
2740
if (exclude_common_ancestry
2434
2741
and (revision is None or len(revision) != 2)):
2435
raise errors.BzrCommandError(
2436
'--exclude-common-ancestry requires -r with two revisions')
2742
raise errors.BzrCommandError(gettext(
2743
'--exclude-common-ancestry requires -r with two revisions'))
2438
2745
if levels is None:
2441
raise errors.BzrCommandError(
2442
'--levels and --include-merges are mutually exclusive')
2748
raise errors.BzrCommandError(gettext(
2749
'{0} and {1} are mutually exclusive').format(
2750
'--levels', '--include-merged'))
2444
2752
if change is not None:
2445
2753
if len(change) > 1:
2446
2754
raise errors.RangeInChangeOption()
2447
2755
if revision is not None:
2448
raise errors.BzrCommandError(
2449
'--revision and --change are mutually exclusive')
2756
raise errors.BzrCommandError(gettext(
2757
'{0} and {1} are mutually exclusive').format(
2758
'--revision', '--change'))
2451
2760
revision = change
2845
3166
self.outf.write("%s\n" % pattern)
2847
3168
if not name_pattern_list:
2848
raise errors.BzrCommandError("ignore requires at least one "
2849
"NAME_PATTERN or --default-rules.")
3169
raise errors.BzrCommandError(gettext("ignore requires at least one "
3170
"NAME_PATTERN or --default-rules."))
2850
3171
name_pattern_list = [globbing.normalize_pattern(p)
2851
3172
for p in name_pattern_list]
2852
3173
bad_patterns = ''
3174
bad_patterns_count = 0
2853
3175
for p in name_pattern_list:
2854
3176
if not globbing.Globster.is_pattern_valid(p):
3177
bad_patterns_count += 1
2855
3178
bad_patterns += ('\n %s' % p)
2856
3179
if bad_patterns:
2857
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
3180
msg = (ngettext('Invalid ignore pattern found. %s',
3181
'Invalid ignore patterns found. %s',
3182
bad_patterns_count) % bad_patterns)
2858
3183
ui.ui_factory.show_error(msg)
2859
3184
raise errors.InvalidPattern('')
2860
3185
for name_pattern in name_pattern_list:
2861
3186
if (name_pattern[0] == '/' or
2862
3187
(len(name_pattern) > 1 and name_pattern[1] == ':')):
2863
raise errors.BzrCommandError(
2864
"NAME_PATTERN should not be an absolute path")
3188
raise errors.BzrCommandError(gettext(
3189
"NAME_PATTERN should not be an absolute path"))
2865
3190
tree, relpath = WorkingTree.open_containing(directory)
2866
3191
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2867
3192
ignored = globbing.Globster(name_pattern_list)
2971
3296
Option('per-file-timestamps',
2972
3297
help='Set modification time of files to that of the last '
2973
3298
'revision in which it was changed.'),
3299
Option('uncommitted',
3300
help='Export the working tree contents rather than that of the '
2975
3303
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2976
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3304
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2977
3306
from bzrlib.export import export
2979
3308
if branch_or_subdir is None:
2980
tree = WorkingTree.open_containing(directory)[0]
3309
branch_or_subdir = directory
3311
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3313
if tree is not None:
3314
self.add_cleanup(tree.lock_read().unlock)
3318
raise errors.BzrCommandError(
3319
gettext("--uncommitted requires a working tree"))
2984
b, subdir = Branch.open_containing(branch_or_subdir)
2987
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3322
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2989
export(rev_tree, dest, format, root, subdir, filtered=filters,
3324
export(export_tree, dest, format, root, subdir, filtered=filters,
2990
3325
per_file_timestamps=per_file_timestamps)
2991
3326
except errors.NoSuchExportFormat, e:
2992
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3327
raise errors.BzrCommandError(
3328
gettext('Unsupported export format: %s') % e.format)
2995
3331
class cmd_cat(Command):
3033
3369
old_file_id = rev_tree.path2id(relpath)
3371
# TODO: Split out this code to something that generically finds the
3372
# best id for a path across one or more trees; it's like
3373
# find_ids_across_trees but restricted to find just one. -- mbp
3035
3375
if name_from_revision:
3036
3376
# Try in revision if requested
3037
3377
if old_file_id is None:
3038
raise errors.BzrCommandError(
3039
"%r is not present in revision %s" % (
3378
raise errors.BzrCommandError(gettext(
3379
"{0!r} is not present in revision {1}").format(
3040
3380
filename, rev_tree.get_revision_id()))
3042
content = rev_tree.get_file_text(old_file_id)
3382
actual_file_id = old_file_id
3044
3384
cur_file_id = tree.path2id(relpath)
3046
if cur_file_id is not None:
3047
# Then try with the actual file id
3049
content = rev_tree.get_file_text(cur_file_id)
3051
except errors.NoSuchId:
3052
# The actual file id didn't exist at that time
3054
if not found and old_file_id is not None:
3055
# Finally try with the old file id
3056
content = rev_tree.get_file_text(old_file_id)
3059
# Can't be found anywhere
3060
raise errors.BzrCommandError(
3061
"%r is not present in revision %s" % (
3385
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3386
actual_file_id = cur_file_id
3387
elif old_file_id is not None:
3388
actual_file_id = old_file_id
3390
raise errors.BzrCommandError(gettext(
3391
"{0!r} is not present in revision {1}").format(
3062
3392
filename, rev_tree.get_revision_id()))
3064
from bzrlib.filters import (
3065
ContentFilterContext,
3066
filtered_output_bytes,
3068
filters = rev_tree._content_filter_stack(relpath)
3069
chunks = content.splitlines(True)
3070
content = filtered_output_bytes(chunks, filters,
3071
ContentFilterContext(relpath, rev_tree))
3073
self.outf.writelines(content)
3394
from bzrlib.filter_tree import ContentFilterTree
3395
filter_tree = ContentFilterTree(rev_tree,
3396
rev_tree._content_filter_stack)
3397
content = filter_tree.get_file_text(actual_file_id)
3076
self.outf.write(content)
3399
content = rev_tree.get_file_text(actual_file_id)
3401
self.outf.write(content)
3079
3404
class cmd_local_time_offset(Command):
3186
3511
aliases = ['ci', 'checkin']
3188
3513
def _iter_bug_fix_urls(self, fixes, branch):
3514
default_bugtracker = None
3189
3515
# Configure the properties for bug fixing attributes.
3190
3516
for fixed_bug in fixes:
3191
3517
tokens = fixed_bug.split(':')
3192
if len(tokens) != 2:
3193
raise errors.BzrCommandError(
3518
if len(tokens) == 1:
3519
if default_bugtracker is None:
3520
branch_config = branch.get_config()
3521
default_bugtracker = branch_config.get_user_option(
3523
if default_bugtracker is None:
3524
raise errors.BzrCommandError(gettext(
3525
"No tracker specified for bug %s. Use the form "
3526
"'tracker:id' or specify a default bug tracker "
3527
"using the `bugtracker` option.\nSee "
3528
"\"bzr help bugs\" for more information on this "
3529
"feature. Commit refused.") % fixed_bug)
3530
tag = default_bugtracker
3532
elif len(tokens) != 2:
3533
raise errors.BzrCommandError(gettext(
3194
3534
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3195
3535
"See \"bzr help bugs\" for more information on this "
3196
"feature.\nCommit refused." % fixed_bug)
3197
tag, bug_id = tokens
3536
"feature.\nCommit refused.") % fixed_bug)
3538
tag, bug_id = tokens
3199
3540
yield bugtracker.get_bug_url(tag, branch, bug_id)
3200
3541
except errors.UnknownBugTrackerAbbreviation:
3201
raise errors.BzrCommandError(
3202
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3542
raise errors.BzrCommandError(gettext(
3543
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3203
3544
except errors.MalformedBugIdentifier, e:
3204
raise errors.BzrCommandError(
3205
"%s\nCommit refused." % (str(e),))
3545
raise errors.BzrCommandError(gettext(
3546
"%s\nCommit refused.") % (str(e),))
3207
3548
def run(self, message=None, file=None, verbose=False, selected_list=None,
3208
3549
unchanged=False, strict=False, local=False, fixes=None,
3315
3659
exclude=tree.safe_relpath_files(exclude),
3317
3661
except PointlessCommit:
3318
raise errors.BzrCommandError("No changes to commit."
3662
raise errors.BzrCommandError(gettext("No changes to commit."
3319
3663
" Please 'bzr add' the files you want to commit, or use"
3320
" --unchanged to force an empty commit.")
3664
" --unchanged to force an empty commit."))
3321
3665
except ConflictsInTree:
3322
raise errors.BzrCommandError('Conflicts detected in working '
3666
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3323
3667
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3325
3669
except StrictCommitFailed:
3326
raise errors.BzrCommandError("Commit refused because there are"
3327
" unknown files in the working tree.")
3670
raise errors.BzrCommandError(gettext("Commit refused because there are"
3671
" unknown files in the working tree."))
3328
3672
except errors.BoundBranchOutOfDate, e:
3329
e.extra_help = ("\n"
3673
e.extra_help = (gettext("\n"
3330
3674
'To commit to master branch, run update and then commit.\n'
3331
3675
'You can also pass --local to commit to continue working '
4540
4897
theirs_only=False,
4541
4898
log_format=None, long=False, short=False, line=False,
4542
4899
show_ids=False, verbose=False, this=False, other=False,
4543
include_merges=False, revision=None, my_revision=None,
4900
include_merged=None, revision=None, my_revision=None,
4902
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4545
4903
from bzrlib.missing import find_unmerged, iter_log_revisions
4546
4904
def message(s):
4547
4905
if not is_quiet():
4548
4906
self.outf.write(s)
4908
if symbol_versioning.deprecated_passed(include_merges):
4909
ui.ui_factory.show_user_warning(
4910
'deprecated_command_option',
4911
deprecated_name='--include-merges',
4912
recommended_name='--include-merged',
4913
deprecated_in_version='2.5',
4914
command=self.invoked_as)
4915
if include_merged is None:
4916
include_merged = include_merges
4918
raise errors.BzrCommandError(gettext(
4919
'{0} and {1} are mutually exclusive').format(
4920
'--include-merges', '--include-merged'))
4921
if include_merged is None:
4922
include_merged = False
4551
4924
mine_only = this
4882
5258
location = b.get_old_bound_location()
4883
5259
except errors.UpgradeRequired:
4884
raise errors.BzrCommandError('No location supplied. '
4885
'This format does not remember old locations.')
5260
raise errors.BzrCommandError(gettext('No location supplied. '
5261
'This format does not remember old locations.'))
4887
5263
if location is None:
4888
5264
if b.get_bound_location() is not None:
4889
raise errors.BzrCommandError('Branch is already bound')
5265
raise errors.BzrCommandError(gettext('Branch is already bound'))
4891
raise errors.BzrCommandError('No location supplied '
4892
'and no previous location known')
5267
raise errors.BzrCommandError(gettext('No location supplied '
5268
'and no previous location known'))
4893
5269
b_other = Branch.open(location)
4895
5271
b.bind(b_other)
4896
5272
except errors.DivergedBranches:
4897
raise errors.BzrCommandError('These branches have diverged.'
4898
' Try merging, and then bind again.')
5273
raise errors.BzrCommandError(gettext('These branches have diverged.'
5274
' Try merging, and then bind again.'))
4899
5275
if b.get_config().has_explicit_nickname():
4900
5276
b.nick = b_other.nick
5005
5384
end_revision=last_revno)
5008
self.outf.write('Dry-run, pretending to remove'
5009
' the above revisions.\n')
5387
self.outf.write(gettext('Dry-run, pretending to remove'
5388
' the above revisions.\n'))
5011
self.outf.write('The above revision(s) will be removed.\n')
5390
self.outf.write(gettext('The above revision(s) will be removed.\n'))
5014
5393
if not ui.ui_factory.confirm_action(
5015
u'Uncommit these revisions',
5394
gettext(u'Uncommit these revisions'),
5016
5395
'bzrlib.builtins.uncommit',
5018
self.outf.write('Canceled\n')
5397
self.outf.write(gettext('Canceled\n'))
5021
5400
mutter('Uncommitting from {%s} to {%s}',
5022
5401
last_rev_id, rev_id)
5023
5402
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5024
revno=revno, local=local)
5025
self.outf.write('You can restore the old tip by running:\n'
5026
' bzr pull . -r revid:%s\n' % last_rev_id)
5403
revno=revno, local=local, keep_tags=keep_tags)
5404
self.outf.write(gettext('You can restore the old tip by running:\n'
5405
' bzr pull . -r revid:%s\n') % last_rev_id)
5029
5408
class cmd_break_lock(Command):
5135
5516
return host, port
5137
5518
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5519
protocol=None, client_timeout=None):
5139
5520
from bzrlib import transport
5140
5521
if directory is None:
5141
5522
directory = os.getcwd()
5142
5523
if protocol is None:
5143
5524
protocol = transport.transport_server_registry.get()
5144
5525
host, port = self.get_host_and_port(port)
5145
url = urlutils.local_path_to_url(directory)
5526
url = transport.location_to_url(directory)
5146
5527
if not allow_writes:
5147
5528
url = 'readonly+' + url
5148
t = transport.get_transport(url)
5149
protocol(t, host, port, inet)
5529
t = transport.get_transport_from_url(url)
5531
protocol(t, host, port, inet, client_timeout)
5532
except TypeError, e:
5533
# We use symbol_versioning.deprecated_in just so that people
5534
# grepping can find it here.
5535
# symbol_versioning.deprecated_in((2, 5, 0))
5536
symbol_versioning.warn(
5537
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5538
'Most likely it needs to be updated to support a'
5539
' "timeout" parameter (added in bzr 2.5.0)'
5540
% (e, protocol.__module__, protocol),
5542
protocol(t, host, port, inet)
5152
5545
class cmd_join(Command):
5564
5957
self.add_cleanup(branch.lock_write().unlock)
5566
5959
if tag_name is None:
5567
raise errors.BzrCommandError("No tag specified to delete.")
5960
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5568
5961
branch.tags.delete_tag(tag_name)
5569
note('Deleted tag %s.' % tag_name)
5962
note(gettext('Deleted tag %s.') % tag_name)
5572
5965
if len(revision) != 1:
5573
raise errors.BzrCommandError(
5966
raise errors.BzrCommandError(gettext(
5574
5967
"Tags can only be placed on a single revision, "
5576
5969
revision_id = revision[0].as_revision_id(branch)
5578
5971
revision_id = branch.last_revision()
5579
5972
if tag_name is None:
5580
5973
tag_name = branch.automatic_tag_name(revision_id)
5581
5974
if tag_name is None:
5582
raise errors.BzrCommandError(
5583
"Please specify a tag name.")
5584
if (not force) and branch.tags.has_tag(tag_name):
5975
raise errors.BzrCommandError(gettext(
5976
"Please specify a tag name."))
5978
existing_target = branch.tags.lookup_tag(tag_name)
5979
except errors.NoSuchTag:
5980
existing_target = None
5981
if not force and existing_target not in (None, revision_id):
5585
5982
raise errors.TagAlreadyExists(tag_name)
5586
branch.tags.set_tag(tag_name, revision_id)
5587
note('Created tag %s.' % tag_name)
5983
if existing_target == revision_id:
5984
note(gettext('Tag %s already exists for that revision.') % tag_name)
5986
branch.tags.set_tag(tag_name, revision_id)
5987
if existing_target is None:
5988
note(gettext('Created tag %s.') % tag_name)
5990
note(gettext('Updated tag %s.') % tag_name)
5590
5993
class cmd_tags(Command):
5682
6087
takes_args = ['location?']
5683
6088
takes_options = [
5684
6089
RegistryOption.from_kwargs(
5686
title='Target type',
5687
help='The type to reconfigure the directory to.',
6092
help='The relation between branch and tree.',
5688
6093
value_switches=True, enum_switch=False,
5689
6094
branch='Reconfigure to be an unbound branch with no working tree.',
5690
6095
tree='Reconfigure to be an unbound branch with a working tree.',
5691
6096
checkout='Reconfigure to be a bound branch with a working tree.',
5692
6097
lightweight_checkout='Reconfigure to be a lightweight'
5693
6098
' checkout (with no local history).',
6100
RegistryOption.from_kwargs(
6102
title='Repository type',
6103
help='Location fo the repository.',
6104
value_switches=True, enum_switch=False,
5694
6105
standalone='Reconfigure to be a standalone branch '
5695
6106
'(i.e. stop using shared repository).',
5696
6107
use_shared='Reconfigure to use a shared repository.',
6109
RegistryOption.from_kwargs(
6111
title='Trees in Repository',
6112
help='Whether new branches in the repository have trees.',
6113
value_switches=True, enum_switch=False,
5697
6114
with_trees='Reconfigure repository to create '
5698
6115
'working trees on branches by default.',
5699
6116
with_no_trees='Reconfigure repository to not create '
5726
6143
# At the moment you can use --stacked-on and a different
5727
6144
# reconfiguration shape at the same time; there seems no good reason
5729
if target_type is None:
6146
if (tree_type is None and
6147
repository_type is None and
6148
repository_trees is None):
5730
6149
if stacked_on or unstacked:
5733
raise errors.BzrCommandError('No target configuration '
5735
elif target_type == 'branch':
6152
raise errors.BzrCommandError(gettext('No target configuration '
6154
reconfiguration = None
6155
if tree_type == 'branch':
5736
6156
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5737
elif target_type == 'tree':
6157
elif tree_type == 'tree':
5738
6158
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
5739
elif target_type == 'checkout':
6159
elif tree_type == 'checkout':
5740
6160
reconfiguration = reconfigure.Reconfigure.to_checkout(
5741
6161
directory, bind_to)
5742
elif target_type == 'lightweight-checkout':
6162
elif tree_type == 'lightweight-checkout':
5743
6163
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
5744
6164
directory, bind_to)
5745
elif target_type == 'use-shared':
6166
reconfiguration.apply(force)
6167
reconfiguration = None
6168
if repository_type == 'use-shared':
5746
6169
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
5747
elif target_type == 'standalone':
6170
elif repository_type == 'standalone':
5748
6171
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
5749
elif target_type == 'with-trees':
6173
reconfiguration.apply(force)
6174
reconfiguration = None
6175
if repository_trees == 'with-trees':
5750
6176
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5751
6177
directory, True)
5752
elif target_type == 'with-no-trees':
6178
elif repository_trees == 'with-no-trees':
5753
6179
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
5754
6180
directory, False)
5755
reconfiguration.apply(force)
6182
reconfiguration.apply(force)
6183
reconfiguration = None
5758
6186
class cmd_switch(Command):
5793
6221
from bzrlib import switch
5794
6222
tree_location = directory
5795
6223
revision = _get_one_revision('switch', revision)
5796
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
6224
possible_transports = []
6225
control_dir = controldir.ControlDir.open_containing(tree_location,
6226
possible_transports=possible_transports)[0]
5797
6227
if to_location is None:
5798
6228
if revision is None:
5799
raise errors.BzrCommandError('You must supply either a'
5800
' revision or a location')
6229
raise errors.BzrCommandError(gettext('You must supply either a'
6230
' revision or a location'))
5801
6231
to_location = tree_location
5803
branch = control_dir.open_branch()
6233
branch = control_dir.open_branch(
6234
possible_transports=possible_transports)
5804
6235
had_explicit_nick = branch.get_config().has_explicit_nickname()
5805
6236
except errors.NotBranchError:
5807
6238
had_explicit_nick = False
5808
6239
if create_branch:
5809
6240
if branch is None:
5810
raise errors.BzrCommandError('cannot create branch without'
5812
to_location = directory_service.directories.dereference(
5814
if '/' not in to_location and '\\' not in to_location:
5815
# This path is meant to be relative to the existing branch
5816
this_url = self._get_branch_location(control_dir)
5817
to_location = urlutils.join(this_url, '..', to_location)
6241
raise errors.BzrCommandError(
6242
gettext('cannot create branch without source branch'))
6243
to_location = lookup_new_sibling_branch(control_dir, to_location,
6244
possible_transports=possible_transports)
5818
6245
to_branch = branch.bzrdir.sprout(to_location,
5819
possible_transports=[branch.bzrdir.root_transport],
5820
source_branch=branch).open_branch()
6246
possible_transports=possible_transports,
6247
source_branch=branch).open_branch()
5823
to_branch = Branch.open(to_location)
5824
except errors.NotBranchError:
5825
this_url = self._get_branch_location(control_dir)
5826
to_branch = Branch.open(
5827
urlutils.join(this_url, '..', to_location))
6249
to_branch = lookup_sibling_branch(control_dir, to_location)
5828
6250
if revision is not None:
5829
6251
revision = revision.as_revision_id(to_branch)
5830
6252
switch.switch(control_dir, to_branch, force, revision_id=revision)
5831
6253
if had_explicit_nick:
5832
6254
branch = control_dir.open_branch() #get the new branch!
5833
6255
branch.nick = to_branch.nick
5834
note('Switched to branch: %s',
6256
note(gettext('Switched to branch: %s'),
5835
6257
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5837
def _get_branch_location(self, control_dir):
5838
"""Return location of branch for this control dir."""
5840
this_branch = control_dir.open_branch()
5841
# This may be a heavy checkout, where we want the master branch
5842
master_location = this_branch.get_bound_location()
5843
if master_location is not None:
5844
return master_location
5845
# If not, use a local sibling
5846
return this_branch.base
5847
except errors.NotBranchError:
5848
format = control_dir.find_branch_format()
5849
if getattr(format, 'get_reference', None) is not None:
5850
return format.get_reference(control_dir)
5852
return control_dir.root_transport.base
5855
6261
class cmd_view(Command):
5946
6352
name = current_view
5949
raise errors.BzrCommandError(
5950
"Both --delete and a file list specified")
6355
raise errors.BzrCommandError(gettext(
6356
"Both --delete and a file list specified"))
5952
raise errors.BzrCommandError(
5953
"Both --delete and --switch specified")
6358
raise errors.BzrCommandError(gettext(
6359
"Both --delete and --switch specified"))
5955
6361
tree.views.set_view_info(None, {})
5956
self.outf.write("Deleted all views.\n")
6362
self.outf.write(gettext("Deleted all views.\n"))
5957
6363
elif name is None:
5958
raise errors.BzrCommandError("No current view to delete")
6364
raise errors.BzrCommandError(gettext("No current view to delete"))
5960
6366
tree.views.delete_view(name)
5961
self.outf.write("Deleted '%s' view.\n" % name)
6367
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5964
raise errors.BzrCommandError(
5965
"Both --switch and a file list specified")
6370
raise errors.BzrCommandError(gettext(
6371
"Both --switch and a file list specified"))
5967
raise errors.BzrCommandError(
5968
"Both --switch and --all specified")
6373
raise errors.BzrCommandError(gettext(
6374
"Both --switch and --all specified"))
5969
6375
elif switch == 'off':
5970
6376
if current_view is None:
5971
raise errors.BzrCommandError("No current view to disable")
6377
raise errors.BzrCommandError(gettext("No current view to disable"))
5972
6378
tree.views.set_view_info(None, view_dict)
5973
self.outf.write("Disabled '%s' view.\n" % (current_view))
6379
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5975
6381
tree.views.set_view_info(switch, view_dict)
5976
6382
view_str = views.view_display_str(tree.views.lookup_view())
5977
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6383
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5980
self.outf.write('Views defined:\n')
6386
self.outf.write(gettext('Views defined:\n'))
5981
6387
for view in sorted(view_dict):
5982
6388
if view == current_view:
5986
6392
view_str = views.view_display_str(view_dict[view])
5987
6393
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
5989
self.outf.write('No views defined.\n')
6395
self.outf.write(gettext('No views defined.\n'))
5990
6396
elif file_list:
5991
6397
if name is None:
5992
6398
# No name given and no current view set
5994
6400
elif name == 'off':
5995
raise errors.BzrCommandError(
5996
"Cannot change the 'off' pseudo view")
6401
raise errors.BzrCommandError(gettext(
6402
"Cannot change the 'off' pseudo view"))
5997
6403
tree.views.set_view(name, sorted(file_list))
5998
6404
view_str = views.view_display_str(tree.views.lookup_view())
5999
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6405
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
6001
6407
# list the files
6002
6408
if name is None:
6003
6409
# No name given and no current view set
6004
self.outf.write('No current view.\n')
6410
self.outf.write(gettext('No current view.\n'))
6006
6412
view_str = views.view_display_str(tree.views.lookup_view(name))
6007
self.outf.write("'%s' view is: %s\n" % (name, view_str))
6413
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
6010
6416
class cmd_hooks(Command):