78
72
_parse_revision_str,
80
74
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
86
def _get_branch_location(control_dir, possible_transports=None):
87
"""Return location of branch for this control dir."""
89
target = control_dir.get_branch_reference()
90
except errors.NotBranchError:
91
return control_dir.root_transport.base
92
if target is not None:
94
this_branch = control_dir.open_branch(
95
possible_transports=possible_transports)
96
# This may be a heavy checkout, where we want the master branch
97
master_location = this_branch.get_bound_location()
98
if master_location is not None:
99
return master_location
100
# If not, use a local sibling
101
return this_branch.base
104
def _is_colocated(control_dir, possible_transports=None):
105
"""Check if the branch in control_dir is colocated.
107
:param control_dir: Control directory
108
:return: Tuple with boolean indicating whether the branch is colocated
109
and the full URL to the actual branch
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 to find sibling branches from
136
:param location: Name of the new branch
137
:return: Full location to the new branch
139
location = directory_service.directories.dereference(location)
140
if '/' not in location and '\\' not in location:
141
(colocated, this_url) = _is_colocated(control_dir, possible_transports)
144
return urlutils.join_segment_parameters(this_url,
145
{"branch": urlutils.escape(location)})
147
return urlutils.join(this_url, '..', urlutils.escape(location))
151
def open_sibling_branch(control_dir, location, possible_transports=None):
152
"""Open a branch, possibly a sibling of another.
154
:param control_dir: Control directory relative to which to lookup the
156
:param location: Location to look up
157
:return: branch to open
160
# Perhaps it's a colocated branch?
161
return control_dir.open_branch(location,
162
possible_transports=possible_transports)
163
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
164
this_url = _get_branch_location(control_dir)
167
this_url, '..', urlutils.escape(location)))
170
def open_nearby_branch(near=None, location=None, possible_transports=None):
171
"""Open a nearby branch.
173
:param near: Optional location of container from which to open branch
174
:param location: Location of the branch
175
:return: Branch instance
181
return Branch.open(location,
182
possible_transports=possible_transports)
183
except errors.NotBranchError:
185
cdir = controldir.ControlDir.open(near,
186
possible_transports=possible_transports)
187
return open_sibling_branch(cdir, location,
188
possible_transports=possible_transports)
191
def iter_sibling_branches(control_dir, possible_transports=None):
192
"""Iterate over the siblings of a branch.
194
:param control_dir: Control directory for which to look up the siblings
195
:return: Iterator over tuples with branch name and branch object
199
reference = control_dir.get_branch_reference()
200
except errors.NotBranchError:
201
# There is no active branch, just return the colocated branches.
202
for name, branch in control_dir.get_branches().iteritems():
205
if reference is not None:
206
ref_branch = Branch.open(reference,
207
possible_transports=possible_transports)
210
if ref_branch is None or ref_branch.name:
211
if ref_branch is not None:
212
control_dir = ref_branch.bzrdir
213
for name, branch in control_dir.get_branches().iteritems():
216
repo = ref_branch.bzrdir.find_repository()
217
for branch in repo.find_branches(using=True):
218
name = urlutils.relative_url(repo.user_url,
219
branch.user_url).rstrip("/")
77
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
80
return internal_tree_files(file_list, default_branch, canonicalize,
223
84
def tree_files_for_add(file_list):
149
# XXX: Bad function name; should possibly also be a class method of
150
# WorkingTree rather than a function.
151
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
152
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
154
"""Convert command-line paths to a WorkingTree and relative paths.
156
Deprecated: use WorkingTree.open_containing_paths instead.
158
This is typically used for command-line processors that take one or
159
more filenames, and infer the workingtree that contains them.
161
The filenames given are not required to exist.
163
:param file_list: Filenames to convert.
165
:param default_branch: Fallback tree path to use if file_list is empty or
168
:param apply_view: if True and a view is set, apply it or check that
169
specified files are within it
171
:return: workingtree, [relative_paths]
173
return WorkingTree.open_containing_paths(
174
file_list, default_directory='.',
288
179
def _get_view_info_for_change_reporter(tree):
289
180
"""Get the view information from a tree for change reporting."""
661
547
_see_also = ['info']
662
548
takes_args = ['location?']
663
549
takes_options = [
664
Option('tree', help='Show revno of working tree.'),
550
Option('tree', help='Show revno of working tree'),
669
def run(self, tree=False, location=u'.', revision=None):
670
if revision is not None and tree:
671
raise errors.BzrCommandError(gettext("--tree and --revision can "
672
"not be used together"))
554
def run(self, tree=False, location=u'.'):
676
557
wt = WorkingTree.open_containing(location)[0]
677
558
self.add_cleanup(wt.lock_read().unlock)
678
559
except (errors.NoWorkingTree, errors.NotLocalUrl):
679
560
raise errors.NoWorkingTree(location)
681
561
revid = wt.last_revision()
563
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
564
except errors.NoSuchRevision:
566
revno = ".".join(str(n) for n in revno_t)
683
568
b = Branch.open_containing(location)[0]
684
569
self.add_cleanup(b.lock_read().unlock)
686
if len(revision) != 1:
687
raise errors.BzrCommandError(gettext(
688
"Revision numbers only make sense for single "
689
"revisions, not ranges"))
690
revid = revision[0].as_revision_id(b)
692
revid = b.last_revision()
694
revno_t = b.revision_id_to_dotted_revno(revid)
695
except errors.NoSuchRevision:
697
revno = ".".join(str(n) for n in revno_t)
698
571
self.cleanup_now()
699
self.outf.write(revno + '\n')
572
self.outf.write(str(revno) + '\n')
702
575
class cmd_revision_info(Command):
859
723
takes_args = ['dir+']
863
help='No error if existing, make parent directories as needed.',
867
724
encoding_type = 'replace'
870
def add_file_with_parents(cls, wt, relpath):
871
if wt.path2id(relpath) is not None:
873
cls.add_file_with_parents(wt, osutils.dirname(relpath))
877
def add_file_single(cls, wt, relpath):
880
def run(self, dir_list, parents=False):
882
add_file = self.add_file_with_parents
884
add_file = self.add_file_single
886
wt, relpath = WorkingTree.open_containing(dir)
891
if e.errno != errno.EEXIST:
726
def run(self, dir_list):
728
wt, dd = WorkingTree.open_containing(d)
729
base = os.path.dirname(dd)
730
id = wt.path2id(base)
734
self.outf.write('added %s\n' % d)
895
add_file(wt, relpath)
897
self.outf.write(gettext('added %s\n') % dir)
736
raise errors.NotVersionedError(path=base)
900
739
class cmd_relpath(Command):
1007
845
return self.run_auto(names_list, after, dry_run)
1009
raise errors.BzrCommandError(gettext('--dry-run requires --auto.'))
847
raise errors.BzrCommandError('--dry-run requires --auto.')
1010
848
if names_list is None:
1012
850
if len(names_list) < 2:
1013
raise errors.BzrCommandError(gettext("missing file argument"))
851
raise errors.BzrCommandError("missing file argument")
1014
852
tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
1015
for file_name in rel_names[0:-1]:
1017
raise errors.BzrCommandError(gettext("can not move root of branch"))
1018
853
self.add_cleanup(tree.lock_tree_write().unlock)
1019
854
self._run(tree, names_list, rel_names, after)
1021
856
def run_auto(self, names_list, after, dry_run):
1022
857
if names_list is not None and len(names_list) > 1:
1023
raise errors.BzrCommandError(gettext('Only one path may be specified to'
858
raise errors.BzrCommandError('Only one path may be specified to'
1026
raise errors.BzrCommandError(gettext('--after cannot be specified with'
861
raise errors.BzrCommandError('--after cannot be specified with'
1028
863
work_tree, file_list = WorkingTree.open_containing_paths(
1029
864
names_list, default_directory='.')
1030
865
self.add_cleanup(work_tree.lock_tree_write().unlock)
1313
1131
Option('no-tree',
1314
1132
help="Don't populate the working tree, even for protocols"
1315
1133
" that support it."),
1316
Option('overwrite-tags',
1317
help="Overwrite tags only."),
1319
1135
takes_args = ['location?']
1320
1136
encoding_type = 'replace'
1322
def run(self, location=None, remember=None, overwrite=False,
1138
def run(self, location=None, remember=False, overwrite=False,
1323
1139
create_prefix=False, verbose=False, revision=None,
1324
1140
use_existing_dir=False, directory=None, stacked_on=None,
1325
stacked=False, strict=None, no_tree=False,
1326
overwrite_tags=False):
1141
stacked=False, strict=None, no_tree=False):
1327
1142
from bzrlib.push import _show_push_branch
1330
overwrite = ["history", "tags"]
1331
elif overwrite_tags:
1332
overwrite = ["tags"]
1336
1144
if directory is None:
1337
1145
directory = '.'
1338
1146
# Get the source branch
1339
1147
(tree, br_from,
1340
_unused) = controldir.ControlDir.open_containing_tree_or_branch(directory)
1148
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1341
1149
# Get the tip's revision_id
1342
1150
revision = _get_one_revision('push', revision)
1343
1151
if revision is not None:
1364
1172
# error by the feedback given to them. RBC 20080227.
1365
1173
stacked_on = parent_url
1366
1174
if not stacked_on:
1367
raise errors.BzrCommandError(gettext(
1368
"Could not determine branch to refer to."))
1175
raise errors.BzrCommandError(
1176
"Could not determine branch to refer to.")
1370
1178
# Get the destination location
1371
1179
if location is None:
1372
1180
stored_loc = br_from.get_push_location()
1373
1181
if stored_loc is None:
1374
parent_loc = br_from.get_parent()
1376
raise errors.BzrCommandError(gettext(
1377
"No push location known or specified. To push to the "
1378
"parent branch (at %s), use 'bzr push :parent'." %
1379
urlutils.unescape_for_display(parent_loc,
1380
self.outf.encoding)))
1382
raise errors.BzrCommandError(gettext(
1383
"No push location known or specified."))
1182
raise errors.BzrCommandError(
1183
"No push location known or specified.")
1385
1185
display_url = urlutils.unescape_for_display(stored_loc,
1386
1186
self.outf.encoding)
1387
note(gettext("Using saved push location: %s") % display_url)
1187
self.outf.write("Using saved push location: %s\n" % display_url)
1388
1188
location = stored_loc
1390
1190
_show_push_branch(br_from, revision_id, location, self.outf,
1468
1268
revision_id = br_from.last_revision()
1469
1269
if to_location is None:
1470
to_location = getattr(br_from, "name", None)
1472
to_location = urlutils.derive_to_location(from_location)
1270
to_location = urlutils.derive_to_location(from_location)
1473
1271
to_transport = transport.get_transport(to_location)
1475
1273
to_transport.mkdir('.')
1476
1274
except errors.FileExists:
1478
to_dir = controldir.ControlDir.open_from_transport(
1480
except errors.NotBranchError:
1481
if not use_existing_dir:
1482
raise errors.BzrCommandError(gettext('Target directory "%s" '
1483
'already exists.') % to_location)
1275
if not use_existing_dir:
1276
raise errors.BzrCommandError('Target directory "%s" '
1277
'already exists.' % to_location)
1488
to_dir.open_branch()
1280
bzrdir.BzrDir.open_from_transport(to_transport)
1489
1281
except errors.NotBranchError:
1492
1284
raise errors.AlreadyBranchError(to_location)
1493
1285
except errors.NoSuchFile:
1494
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1286
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1500
# preserve whatever source format we have.
1501
to_dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1502
possible_transports=[to_transport],
1503
accelerator_tree=accelerator_tree,
1504
hardlink=hardlink, stacked=stacked,
1505
force_new_repo=standalone,
1506
create_tree_if_local=not no_tree,
1507
source_branch=br_from)
1508
branch = to_dir.open_branch(
1509
possible_transports=[
1510
br_from.bzrdir.root_transport, to_transport])
1511
except errors.NoSuchRevision:
1512
to_transport.delete_tree('.')
1513
msg = gettext("The branch {0} has no revision {1}.").format(
1514
from_location, revision)
1515
raise errors.BzrCommandError(msg)
1518
to_repo = to_dir.open_repository()
1519
except errors.NoRepositoryPresent:
1520
to_repo = to_dir.create_repository()
1521
to_repo.fetch(br_from.repository, revision_id=revision_id)
1522
branch = br_from.sprout(to_dir, revision_id=revision_id)
1289
# preserve whatever source format we have.
1290
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1291
possible_transports=[to_transport],
1292
accelerator_tree=accelerator_tree,
1293
hardlink=hardlink, stacked=stacked,
1294
force_new_repo=standalone,
1295
create_tree_if_local=not no_tree,
1296
source_branch=br_from)
1297
branch = dir.open_branch()
1298
except errors.NoSuchRevision:
1299
to_transport.delete_tree('.')
1300
msg = "The branch %s has no revision %s." % (from_location,
1302
raise errors.BzrCommandError(msg)
1523
1303
_merge_tags_if_possible(br_from, branch)
1524
1304
# If the source branch is stacked, the new branch may
1525
1305
# be stacked whether we asked for that explicitly or not.
1526
1306
# We therefore need a try/except here and not just 'if stacked:'
1528
note(gettext('Created new stacked branch referring to %s.') %
1308
note('Created new stacked branch referring to %s.' %
1529
1309
branch.get_stacked_on_url())
1530
1310
except (errors.NotStacked, errors.UnstackableBranchFormat,
1531
1311
errors.UnstackableRepositoryFormat), e:
1532
note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
1312
note('Branched %d revision(s).' % branch.revno())
1534
1314
# Bind to the parent
1535
1315
parent_branch = Branch.open(from_location)
1536
1316
branch.bind(parent_branch)
1537
note(gettext('New branch bound to %s') % from_location)
1317
note('New branch bound to %s' % from_location)
1539
1319
# Switch to the new branch
1540
1320
wt, _ = WorkingTree.open_containing('.')
1541
1321
_mod_switch.switch(wt.bzrdir, branch)
1542
note(gettext('Switched to branch: %s'),
1322
note('Switched to branch: %s',
1543
1323
urlutils.unescape_for_display(branch.base, 'utf-8'))
1546
class cmd_branches(Command):
1547
__doc__ = """List the branches available at the current location.
1549
This command will print the names of all the branches at the current
1553
takes_args = ['location?']
1555
Option('recursive', short_name='R',
1556
help='Recursively scan for branches rather than '
1557
'just looking in the specified location.')]
1559
def run(self, location=".", recursive=False):
1561
t = transport.get_transport(location)
1562
if not t.listable():
1563
raise errors.BzrCommandError(
1564
"Can't scan this type of location.")
1565
for b in controldir.ControlDir.find_branches(t):
1566
self.outf.write("%s\n" % urlutils.unescape_for_display(
1567
urlutils.relative_url(t.base, b.base),
1568
self.outf.encoding).rstrip("/"))
1570
dir = controldir.ControlDir.open_containing(location)[0]
1572
active_branch = dir.open_branch(name="")
1573
except errors.NotBranchError:
1574
active_branch = None
1576
for name, branch in iter_sibling_branches(dir):
1579
active = (active_branch is not None and
1580
active_branch.base == branch.base)
1581
names[name] = active
1582
# Only mention the current branch explicitly if it's not
1583
# one of the colocated branches
1584
if not any(names.values()) and active_branch is not None:
1585
self.outf.write("* %s\n" % gettext("(default)"))
1586
for name in sorted(names.keys()):
1587
active = names[name]
1592
self.outf.write("%s %s\n" % (
1593
prefix, name.encode(self.outf.encoding)))
1596
1326
class cmd_checkout(Command):
1597
1327
__doc__ = """Create a new checkout of an existing branch.
1698
1430
class cmd_update(Command):
1699
__doc__ = """Update a working tree to a new revision.
1701
This will perform a merge of the destination revision (the tip of the
1702
branch, or the specified revision) into the working tree, and then make
1703
that revision the basis revision for the working tree.
1705
You can use this to visit an older revision, or to update a working tree
1706
that is out of date from its branch.
1708
If there are any uncommitted changes in the tree, they will be carried
1709
across and remain as uncommitted changes after the update. To discard
1710
these changes, use 'bzr revert'. The uncommitted changes may conflict
1711
with the changes brought in by the change in basis revision.
1713
If the tree's branch is bound to a master branch, bzr will also update
1431
__doc__ = """Update a tree to have the latest code committed to its branch.
1433
This will perform a merge into the working tree, and may generate
1434
conflicts. If you have any local changes, you will still
1435
need to commit them after the update for the update to be complete.
1437
If you want to discard your local changes, you can just do a
1438
'bzr revert' instead of 'bzr commit' after the update.
1440
If you want to restore a file that has been removed locally, use
1441
'bzr revert' instead of 'bzr update'.
1443
If the tree's branch is bound to a master branch, it will also update
1714
1444
the branch from the master.
1716
You cannot update just a single file or directory, because each Bazaar
1717
working tree has just a single basis revision. If you want to restore a
1718
file that has been removed locally, use 'bzr revert' instead of 'bzr
1719
update'. If you want to restore a file to its state in a previous
1720
revision, use 'bzr revert' with a '-r' option, or use 'bzr cat' to write
1721
out the old content of that file to a new location.
1723
The 'dir' argument, if given, must be the location of the root of a
1724
working tree to update. By default, the working tree that contains the
1725
current working directory is used.
1728
1447
_see_also = ['pull', 'working-trees', 'status-flags']
1790
1501
old_tip=old_tip,
1791
1502
show_base=show_base)
1792
1503
except errors.NoSuchRevision, e:
1793
raise errors.BzrCommandError(gettext(
1504
raise errors.BzrCommandError(
1794
1505
"branch has no revision %s\n"
1795
1506
"bzr update --revision only works"
1796
" for a revision in the branch history")
1507
" for a revision in the branch history"
1797
1508
% (e.revision))
1798
1509
revno = tree.branch.revision_id_to_dotted_revno(
1799
1510
_mod_revision.ensure_null(tree.last_revision()))
1800
note(gettext('Updated to revision {0} of branch {1}').format(
1801
'.'.join(map(str, revno)), branch_location))
1511
note('Updated to revision %s of branch %s' %
1512
('.'.join(map(str, revno)), branch_location))
1802
1513
parent_ids = tree.get_parent_ids()
1803
1514
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1804
note(gettext('Your local commits will now show as pending merges with '
1805
"'bzr status', and can be committed with 'bzr commit'."))
1515
note('Your local commits will now show as pending merges with '
1516
"'bzr status', and can be committed with 'bzr commit'.")
1806
1517
if conflicts != 0:
1870
1581
title='Deletion Strategy', value_switches=True, enum_switch=False,
1871
1582
safe='Backup changed files (default).',
1872
1583
keep='Delete from bzr but leave the working copy.',
1873
no_backup='Don\'t backup changed files.'),
1584
no_backup='Don\'t backup changed files.',
1585
force='Delete all the specified files, even if they can not be '
1586
'recovered and even if they are non-empty directories. '
1587
'(deprecated, use no-backup)')]
1875
1588
aliases = ['rm', 'del']
1876
1589
encoding_type = 'replace'
1878
1591
def run(self, file_list, verbose=False, new=False,
1879
1592
file_deletion_strategy='safe'):
1593
if file_deletion_strategy == 'force':
1594
note("(The --force option is deprecated, rather use --no-backup "
1596
file_deletion_strategy = 'no-backup'
1881
1598
tree, file_list = WorkingTree.open_containing_paths(file_list)
2197
1905
def run(self, location, format=None, no_trees=False):
2198
1906
if format is None:
2199
format = controldir.format_registry.make_bzrdir('default')
1907
format = bzrdir.format_registry.make_bzrdir('default')
2201
1909
if location is None:
2204
1912
to_transport = transport.get_transport(location)
1913
to_transport.ensure_base()
2206
(repo, newdir, require_stacking, repository_policy) = (
2207
format.initialize_on_transport_ex(to_transport,
2208
create_prefix=True, make_working_trees=not no_trees,
2209
shared_repo=True, force_new_repo=True,
2210
use_existing_dir=True,
2211
repo_format_name=format.repository_format.get_format_string()))
1915
newdir = format.initialize_on_transport(to_transport)
1916
repo = newdir.create_repository(shared=True)
1917
repo.set_make_working_trees(not no_trees)
2212
1918
if not is_quiet():
2213
1919
from bzrlib.info import show_bzrdir_info
2214
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
1920
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2217
1923
class cmd_diff(Command):
2683
2381
Option('show-diff',
2684
2382
short_name='p',
2685
2383
help='Show changes made in each revision as a patch.'),
2686
Option('include-merged',
2384
Option('include-merges',
2687
2385
help='Show merged revisions like --levels 0 does.'),
2688
Option('include-merges', hidden=True,
2689
help='Historical alias for --include-merged.'),
2690
Option('omit-merges',
2691
help='Do not report commits with more than one parent.'),
2692
2386
Option('exclude-common-ancestry',
2693
2387
help='Display only the revisions that are not part'
2694
' of both ancestries (require -rX..Y).'
2696
Option('signatures',
2697
help='Show digital signature validity.'),
2700
help='Show revisions whose properties match this '
2703
ListOption('match-message',
2704
help='Show revisions whose message matches this '
2707
ListOption('match-committer',
2708
help='Show revisions whose committer matches this '
2711
ListOption('match-author',
2712
help='Show revisions whose authors match this '
2715
ListOption('match-bugs',
2716
help='Show revisions whose bugs match this '
2388
' of both ancestries (require -rX..Y)'
2720
2391
encoding_type = 'replace'
2749
2412
_get_info_for_log_files,
2751
2414
direction = (forward and 'forward') or 'reverse'
2752
if symbol_versioning.deprecated_passed(include_merges):
2753
ui.ui_factory.show_user_warning(
2754
'deprecated_command_option',
2755
deprecated_name='--include-merges',
2756
recommended_name='--include-merged',
2757
deprecated_in_version='2.5',
2758
command=self.invoked_as)
2759
if include_merged is None:
2760
include_merged = include_merges
2762
raise errors.BzrCommandError(gettext(
2763
'{0} and {1} are mutually exclusive').format(
2764
'--include-merges', '--include-merged'))
2765
if include_merged is None:
2766
include_merged = False
2767
2415
if (exclude_common_ancestry
2768
2416
and (revision is None or len(revision) != 2)):
2769
raise errors.BzrCommandError(gettext(
2770
'--exclude-common-ancestry requires -r with two revisions'))
2417
raise errors.BzrCommandError(
2418
'--exclude-common-ancestry requires -r with two revisions')
2772
2420
if levels is None:
2775
raise errors.BzrCommandError(gettext(
2776
'{0} and {1} are mutually exclusive').format(
2777
'--levels', '--include-merged'))
2423
raise errors.BzrCommandError(
2424
'--levels and --include-merges are mutually exclusive')
2779
2426
if change is not None:
2780
2427
if len(change) > 1:
2781
2428
raise errors.RangeInChangeOption()
2782
2429
if revision is not None:
2783
raise errors.BzrCommandError(gettext(
2784
'{0} and {1} are mutually exclusive').format(
2785
'--revision', '--change'))
2430
raise errors.BzrCommandError(
2431
'--revision and --change are mutually exclusive')
2787
2433
revision = change
3193
2819
self.outf.write("%s\n" % pattern)
3195
2821
if not name_pattern_list:
3196
raise errors.BzrCommandError(gettext("ignore requires at least one "
3197
"NAME_PATTERN or --default-rules."))
2822
raise errors.BzrCommandError("ignore requires at least one "
2823
"NAME_PATTERN or --default-rules.")
3198
2824
name_pattern_list = [globbing.normalize_pattern(p)
3199
2825
for p in name_pattern_list]
3200
2826
bad_patterns = ''
3201
bad_patterns_count = 0
3202
2827
for p in name_pattern_list:
3203
2828
if not globbing.Globster.is_pattern_valid(p):
3204
bad_patterns_count += 1
3205
2829
bad_patterns += ('\n %s' % p)
3206
2830
if bad_patterns:
3207
msg = (ngettext('Invalid ignore pattern found. %s',
3208
'Invalid ignore patterns found. %s',
3209
bad_patterns_count) % bad_patterns)
2831
msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
3210
2832
ui.ui_factory.show_error(msg)
3211
2833
raise errors.InvalidPattern('')
3212
2834
for name_pattern in name_pattern_list:
3213
2835
if (name_pattern[0] == '/' or
3214
2836
(len(name_pattern) > 1 and name_pattern[1] == ':')):
3215
raise errors.BzrCommandError(gettext(
3216
"NAME_PATTERN should not be an absolute path"))
2837
raise errors.BzrCommandError(
2838
"NAME_PATTERN should not be an absolute path")
3217
2839
tree, relpath = WorkingTree.open_containing(directory)
3218
2840
ignores.tree_ignores_add_patterns(tree, name_pattern_list)
3219
2841
ignored = globbing.Globster(name_pattern_list)
3323
2945
Option('per-file-timestamps',
3324
2946
help='Set modification time of files to that of the last '
3325
2947
'revision in which it was changed.'),
3326
Option('uncommitted',
3327
help='Export the working tree contents rather than that of the '
3330
2949
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3331
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
2950
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3333
2951
from bzrlib.export import export
3335
2953
if branch_or_subdir is None:
3336
branch_or_subdir = directory
3338
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3340
if tree is not None:
3341
self.add_cleanup(tree.lock_read().unlock)
3345
raise errors.BzrCommandError(
3346
gettext("--uncommitted requires a working tree"))
2954
tree = WorkingTree.open_containing(directory)[0]
3349
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2958
b, subdir = Branch.open_containing(branch_or_subdir)
2961
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3351
export(export_tree, dest, format, root, subdir, filtered=filters,
2963
export(rev_tree, dest, format, root, subdir, filtered=filters,
3352
2964
per_file_timestamps=per_file_timestamps)
3353
2965
except errors.NoSuchExportFormat, e:
3354
raise errors.BzrCommandError(
3355
gettext('Unsupported export format: %s') % e.format)
2966
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3358
2969
class cmd_cat(Command):
3396
3007
old_file_id = rev_tree.path2id(relpath)
3398
# TODO: Split out this code to something that generically finds the
3399
# best id for a path across one or more trees; it's like
3400
# find_ids_across_trees but restricted to find just one. -- mbp
3402
3009
if name_from_revision:
3403
3010
# Try in revision if requested
3404
3011
if old_file_id is None:
3405
raise errors.BzrCommandError(gettext(
3406
"{0!r} is not present in revision {1}").format(
3012
raise errors.BzrCommandError(
3013
"%r is not present in revision %s" % (
3407
3014
filename, rev_tree.get_revision_id()))
3409
actual_file_id = old_file_id
3016
content = rev_tree.get_file_text(old_file_id)
3411
3018
cur_file_id = tree.path2id(relpath)
3412
if cur_file_id is not None and rev_tree.has_id(cur_file_id):
3413
actual_file_id = cur_file_id
3414
elif old_file_id is not None:
3415
actual_file_id = old_file_id
3417
raise errors.BzrCommandError(gettext(
3418
"{0!r} is not present in revision {1}").format(
3020
if cur_file_id is not None:
3021
# Then try with the actual file id
3023
content = rev_tree.get_file_text(cur_file_id)
3025
except errors.NoSuchId:
3026
# The actual file id didn't exist at that time
3028
if not found and old_file_id is not None:
3029
# Finally try with the old file id
3030
content = rev_tree.get_file_text(old_file_id)
3033
# Can't be found anywhere
3034
raise errors.BzrCommandError(
3035
"%r is not present in revision %s" % (
3419
3036
filename, rev_tree.get_revision_id()))
3421
from bzrlib.filter_tree import ContentFilterTree
3422
filter_tree = ContentFilterTree(rev_tree,
3423
rev_tree._content_filter_stack)
3424
content = filter_tree.get_file_text(actual_file_id)
3038
from bzrlib.filters import (
3039
ContentFilterContext,
3040
filtered_output_bytes,
3042
filters = rev_tree._content_filter_stack(relpath)
3043
chunks = content.splitlines(True)
3044
content = filtered_output_bytes(chunks, filters,
3045
ContentFilterContext(relpath, rev_tree))
3047
self.outf.writelines(content)
3426
content = rev_tree.get_file_text(actual_file_id)
3428
self.outf.write(content)
3050
self.outf.write(content)
3431
3053
class cmd_local_time_offset(Command):
3538
3160
aliases = ['ci', 'checkin']
3540
3162
def _iter_bug_fix_urls(self, fixes, branch):
3541
default_bugtracker = None
3542
3163
# Configure the properties for bug fixing attributes.
3543
3164
for fixed_bug in fixes:
3544
3165
tokens = fixed_bug.split(':')
3545
if len(tokens) == 1:
3546
if default_bugtracker is None:
3547
branch_config = branch.get_config_stack()
3548
default_bugtracker = branch_config.get(
3550
if default_bugtracker is None:
3551
raise errors.BzrCommandError(gettext(
3552
"No tracker specified for bug %s. Use the form "
3553
"'tracker:id' or specify a default bug tracker "
3554
"using the `bugtracker` option.\nSee "
3555
"\"bzr help bugs\" for more information on this "
3556
"feature. Commit refused.") % fixed_bug)
3557
tag = default_bugtracker
3559
elif len(tokens) != 2:
3560
raise errors.BzrCommandError(gettext(
3166
if len(tokens) != 2:
3167
raise errors.BzrCommandError(
3561
3168
"Invalid bug %s. Must be in the form of 'tracker:id'. "
3562
3169
"See \"bzr help bugs\" for more information on this "
3563
"feature.\nCommit refused.") % fixed_bug)
3565
tag, bug_id = tokens
3170
"feature.\nCommit refused." % fixed_bug)
3171
tag, bug_id = tokens
3567
3173
yield bugtracker.get_bug_url(tag, branch, bug_id)
3568
3174
except errors.UnknownBugTrackerAbbreviation:
3569
raise errors.BzrCommandError(gettext(
3570
'Unrecognized bug %s. Commit refused.') % fixed_bug)
3175
raise errors.BzrCommandError(
3176
'Unrecognized bug %s. Commit refused.' % fixed_bug)
3571
3177
except errors.MalformedBugIdentifier, e:
3572
raise errors.BzrCommandError(gettext(
3573
"%s\nCommit refused.") % (str(e),))
3178
raise errors.BzrCommandError(
3179
"%s\nCommit refused." % (str(e),))
3575
3181
def run(self, message=None, file=None, verbose=False, selected_list=None,
3576
3182
unchanged=False, strict=False, local=False, fixes=None,
3657
3262
# make_commit_message_template_encoded returns user encoding.
3658
3263
# We probably want to be using edit_commit_message instead to
3660
my_message = set_commit_message(commit_obj)
3661
if my_message is None:
3662
start_message = generate_commit_message_template(commit_obj)
3663
my_message = edit_commit_message_encoded(text,
3664
start_message=start_message)
3665
if my_message is None:
3666
raise errors.BzrCommandError(gettext("please specify a commit"
3667
" message with either --message or --file"))
3668
if my_message == "":
3669
raise errors.BzrCommandError(gettext("Empty commit message specified."
3670
" Please specify a commit message with either"
3671
" --message or --file or leave a blank message"
3672
" with --message \"\"."))
3265
start_message = generate_commit_message_template(commit_obj)
3266
my_message = edit_commit_message_encoded(text,
3267
start_message=start_message)
3268
if my_message is None:
3269
raise errors.BzrCommandError("please specify a commit"
3270
" message with either --message or --file")
3271
if my_message == "":
3272
raise errors.BzrCommandError("empty commit message specified")
3673
3273
return my_message
3675
3275
# The API permits a commit with a filter of [] to mean 'select nothing'
3686
3286
exclude=tree.safe_relpath_files(exclude),
3688
3288
except PointlessCommit:
3689
raise errors.BzrCommandError(gettext("No changes to commit."
3289
raise errors.BzrCommandError("No changes to commit."
3690
3290
" Please 'bzr add' the files you want to commit, or use"
3691
" --unchanged to force an empty commit."))
3291
" --unchanged to force an empty commit.")
3692
3292
except ConflictsInTree:
3693
raise errors.BzrCommandError(gettext('Conflicts detected in working '
3293
raise errors.BzrCommandError('Conflicts detected in working '
3694
3294
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
3696
3296
except StrictCommitFailed:
3697
raise errors.BzrCommandError(gettext("Commit refused because there are"
3698
" unknown files in the working tree."))
3297
raise errors.BzrCommandError("Commit refused because there are"
3298
" unknown files in the working tree.")
3699
3299
except errors.BoundBranchOutOfDate, e:
3700
e.extra_help = (gettext("\n"
3300
e.extra_help = ("\n"
3701
3301
'To commit to master branch, run update and then commit.\n'
3702
3302
'You can also pass --local to commit to continue working '
4282
3846
through OTHER, excluding BASE but including OTHER, will be merged. If this
4283
3847
causes some revisions to be skipped, i.e. if the destination branch does
4284
3848
not already contain revision BASE, such a merge is commonly referred to as
4285
a "cherrypick". Unlike a normal merge, Bazaar does not currently track
4286
cherrypicks. The changes look like a normal commit, and the history of the
4287
changes from the other branch is not stored in the commit.
4289
3851
Revision numbers are always relative to the source branch.
4291
3853
Merge will do its best to combine the changes in two branches, but there
4292
3854
are some kinds of problems only a human can fix. When it encounters those,
4293
3855
it will mark a conflict. A conflict means that you need to fix something,
4294
before you can commit.
3856
before you should commit.
4296
3858
Use bzr resolve when you have fixed a problem. See also bzr conflicts.
4298
If there is no default branch set, the first merge will set it (use
4299
--no-remember to avoid setting it). After that, you can omit the branch
4300
to use the default. To change the default, use --remember. The value will
4301
only be saved if the remote location can be accessed.
3860
If there is no default branch set, the first merge will set it. After
3861
that, you can omit the branch to use the default. To change the
3862
default, use --remember. The value will only be saved if the remote
3863
location can be accessed.
4303
3865
The results of the merge are placed into the destination working
4304
3866
directory, where they can be reviewed (with bzr diff), tested, and then
4305
3867
committed to record the result of the merge.
4307
3869
merge refuses to run if there are any uncommitted changes, unless
4308
--force is given. If --force is given, then the changes from the source
4309
will be merged with the current working tree, including any uncommitted
4310
changes in the tree. The --force option can also be used to create a
3870
--force is given. The --force option can also be used to create a
4311
3871
merge revision which has more than two parents.
4313
3873
If one would like to merge changes from the working tree of the other
4441
3997
self.sanity_check_merger(merger)
4442
3998
if (merger.base_rev_id == merger.other_rev_id and
4443
3999
merger.other_rev_id is not None):
4444
# check if location is a nonexistent file (and not a branch) to
4445
# disambiguate the 'Nothing to do'
4446
if merger.interesting_files:
4447
if not merger.other_tree.has_filename(
4448
merger.interesting_files[0]):
4449
note(gettext("merger: ") + str(merger))
4450
raise errors.PathsDoNotExist([location])
4451
note(gettext('Nothing to do.'))
4000
note('Nothing to do.')
4453
if pull and not preview:
4454
4003
if merger.interesting_files is not None:
4455
raise errors.BzrCommandError(gettext('Cannot pull individual files'))
4004
raise errors.BzrCommandError('Cannot pull individual files')
4456
4005
if (merger.base_rev_id == tree.last_revision()):
4457
4006
result = tree.pull(merger.other_branch, False,
4458
4007
merger.other_rev_id)
4459
4008
result.report(self.outf)
4461
4010
if merger.this_basis is None:
4462
raise errors.BzrCommandError(gettext(
4011
raise errors.BzrCommandError(
4463
4012
"This branch has no commits."
4464
" (perhaps you would prefer 'bzr pull')"))
4013
" (perhaps you would prefer 'bzr pull')")
4466
4015
return self._do_preview(merger)
4467
4016
elif interactive:
4747
4289
class cmd_revert(Command):
4749
Set files in the working tree back to the contents of a previous revision.
4290
__doc__ = """Revert files to a previous revision.
4751
4292
Giving a list of files will revert only those files. Otherwise, all files
4752
4293
will be reverted. If the revision is not specified with '--revision', the
4753
working tree basis revision is used. A revert operation affects only the
4754
working tree, not any revision history like the branch and repository or
4755
the working tree basis revision.
4294
last committed revision is used.
4757
4296
To remove only some changes, without reverting to a prior version, use
4758
4297
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4759
4298
will remove the changes introduced by the second last commit (-2), without
4760
4299
affecting the changes introduced by the last commit (-1). To remove
4761
4300
certain changes on a hunk-by-hunk basis, see the shelve command.
4762
To update the branch to a specific revision or the latest revision and
4763
update the working tree accordingly while preserving local changes, see the
4766
Uncommitted changes to files that are reverted will be discarded.
4767
Howver, by default, any files that have been manually changed will be
4768
backed up first. (Files changed only by merge are not backed up.) Backup
4769
files have '.~#~' appended to their name, where # is a number.
4302
By default, any files that have been manually changed will be backed up
4303
first. (Files changed only by merge are not backed up.) Backup files have
4304
'.~#~' appended to their name, where # is a number.
4771
4306
When you provide files, you can use their current pathname or the pathname
4772
4307
from the target revision. So you can use revert to "undelete" a file by
4935
4468
theirs_only=False,
4936
4469
log_format=None, long=False, short=False, line=False,
4937
4470
show_ids=False, verbose=False, this=False, other=False,
4938
include_merged=None, revision=None, my_revision=None,
4940
include_merges=symbol_versioning.DEPRECATED_PARAMETER):
4471
include_merges=False, revision=None, my_revision=None,
4941
4473
from bzrlib.missing import find_unmerged, iter_log_revisions
4942
4474
def message(s):
4943
4475
if not is_quiet():
4944
4476
self.outf.write(s)
4946
if symbol_versioning.deprecated_passed(include_merges):
4947
ui.ui_factory.show_user_warning(
4948
'deprecated_command_option',
4949
deprecated_name='--include-merges',
4950
recommended_name='--include-merged',
4951
deprecated_in_version='2.5',
4952
command=self.invoked_as)
4953
if include_merged is None:
4954
include_merged = include_merges
4956
raise errors.BzrCommandError(gettext(
4957
'{0} and {1} are mutually exclusive').format(
4958
'--include-merges', '--include-merged'))
4959
if include_merged is None:
4960
include_merged = False
4962
4479
mine_only = this
5035
4546
if remote_extra and not mine_only:
5036
4547
if printed_local is True:
5037
4548
message("\n\n\n")
5038
message(ngettext("You are missing %d revision:\n",
5039
"You are missing %d revisions:\n",
5040
len(remote_extra)) %
4549
message("You are missing %d revision(s):\n" %
5041
4550
len(remote_extra))
5042
if remote_branch.supports_tags():
5043
rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5044
4551
for revision in iter_log_revisions(remote_extra,
5045
4552
remote_branch.repository,
5048
4554
lf.log_revision(revision)
5049
4555
status_code = 1
5051
4557
if mine_only and not local_extra:
5052
4558
# We checked local, and found nothing extra
5053
message(gettext('This branch has no new revisions.\n'))
4559
message('This branch is up to date.\n')
5054
4560
elif theirs_only and not remote_extra:
5055
4561
# We checked remote, and found nothing extra
5056
message(gettext('Other branch has no new revisions.\n'))
4562
message('Other branch is up to date.\n')
5057
4563
elif not (mine_only or theirs_only or local_extra or
5059
4565
# We checked both branches, and neither one had extra
5061
message(gettext("Branches are up to date.\n"))
4567
message("Branches are up to date.\n")
5062
4568
self.cleanup_now()
5063
4569
if not status_code and parent is None and other_branch is not None:
5064
4570
self.add_cleanup(local_branch.lock_write().unlock)
5304
4807
location = b.get_old_bound_location()
5305
4808
except errors.UpgradeRequired:
5306
raise errors.BzrCommandError(gettext('No location supplied. '
5307
'This format does not remember old locations.'))
4809
raise errors.BzrCommandError('No location supplied. '
4810
'This format does not remember old locations.')
5309
4812
if location is None:
5310
4813
if b.get_bound_location() is not None:
5311
raise errors.BzrCommandError(
5312
gettext('Branch is already bound'))
4814
raise errors.BzrCommandError('Branch is already bound')
5314
raise errors.BzrCommandError(
5315
gettext('No location supplied'
5316
' and no previous location known'))
4816
raise errors.BzrCommandError('No location supplied '
4817
'and no previous location known')
5317
4818
b_other = Branch.open(location)
5319
4820
b.bind(b_other)
5320
4821
except errors.DivergedBranches:
5321
raise errors.BzrCommandError(gettext('These branches have diverged.'
5322
' Try merging, and then bind again.'))
4822
raise errors.BzrCommandError('These branches have diverged.'
4823
' Try merging, and then bind again.')
5323
4824
if b.get_config().has_explicit_nickname():
5324
4825
b.nick = b_other.nick
5432
4930
end_revision=last_revno)
5435
self.outf.write(gettext('Dry-run, pretending to remove'
5436
' the above revisions.\n'))
4933
self.outf.write('Dry-run, pretending to remove'
4934
' the above revisions.\n')
5438
self.outf.write(gettext('The above revision(s) will be removed.\n'))
4936
self.outf.write('The above revision(s) will be removed.\n')
5441
4939
if not ui.ui_factory.confirm_action(
5442
gettext(u'Uncommit these revisions'),
4940
'Uncommit these revisions',
5443
4941
'bzrlib.builtins.uncommit',
5445
self.outf.write(gettext('Canceled\n'))
4943
self.outf.write('Canceled\n')
5448
4946
mutter('Uncommitting from {%s} to {%s}',
5449
4947
last_rev_id, rev_id)
5450
4948
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5451
revno=revno, local=local, keep_tags=keep_tags)
5452
self.outf.write(gettext('You can restore the old tip by running:\n'
5453
' bzr pull . -r revid:%s\n') % last_rev_id)
4949
revno=revno, local=local)
4950
self.outf.write('You can restore the old tip by running:\n'
4951
' bzr pull . -r revid:%s\n' % last_rev_id)
5456
4954
class cmd_break_lock(Command):
5541
5038
'option leads to global uncontrolled write access to your '
5544
Option('client-timeout', type=float,
5545
help='Override the default idle client timeout (5min).'),
5548
def run(self, listen=None, port=None, inet=False, directory=None,
5549
allow_writes=False, protocol=None, client_timeout=None):
5043
def get_host_and_port(self, port):
5044
"""Return the host and port to run the smart server on.
5046
If 'port' is None, None will be returned for the host and port.
5048
If 'port' has a colon in it, the string before the colon will be
5049
interpreted as the host.
5051
:param port: A string of the port to run the server on.
5052
:return: A tuple of (host, port), where 'host' is a host name or IP,
5053
and port is an integer TCP/IP port.
5056
if port is not None:
5058
host, port = port.split(':')
5062
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5550
5064
from bzrlib import transport
5551
5065
if directory is None:
5552
5066
directory = os.getcwd()
5553
5067
if protocol is None:
5554
5068
protocol = transport.transport_server_registry.get()
5555
url = transport.location_to_url(directory)
5069
host, port = self.get_host_and_port(port)
5070
url = urlutils.local_path_to_url(directory)
5556
5071
if not allow_writes:
5557
5072
url = 'readonly+' + url
5558
t = transport.get_transport_from_url(url)
5559
protocol(t, listen, port, inet, client_timeout)
5073
t = transport.get_transport(url)
5074
protocol(t, host, port, inet)
5562
5077
class cmd_join(Command):
5692
5207
if submit_branch is None:
5693
5208
submit_branch = branch.get_parent()
5694
5209
if submit_branch is None:
5695
raise errors.BzrCommandError(gettext('No submit branch specified or known'))
5210
raise errors.BzrCommandError('No submit branch specified or known')
5697
5212
stored_public_branch = branch.get_public_branch()
5698
5213
if public_branch is None:
5699
5214
public_branch = stored_public_branch
5700
5215
elif stored_public_branch is None:
5701
# FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5702
5216
branch.set_public_branch(public_branch)
5703
5217
if not include_bundle and public_branch is None:
5704
raise errors.BzrCommandError(gettext('No public branch specified or'
5218
raise errors.BzrCommandError('No public branch specified or'
5706
5220
base_revision_id = None
5707
5221
if revision is not None:
5708
5222
if len(revision) > 2:
5709
raise errors.BzrCommandError(gettext('bzr merge-directive takes '
5710
'at most two one revision identifiers'))
5223
raise errors.BzrCommandError('bzr merge-directive takes '
5224
'at most two one revision identifiers')
5711
5225
revision_id = revision[-1].as_revision_id(branch)
5712
5226
if len(revision) == 2:
5713
5227
base_revision_id = revision[0].as_revision_id(branch)
5975
5483
self.add_cleanup(branch.lock_write().unlock)
5977
5485
if tag_name is None:
5978
raise errors.BzrCommandError(gettext("No tag specified to delete."))
5486
raise errors.BzrCommandError("No tag specified to delete.")
5979
5487
branch.tags.delete_tag(tag_name)
5980
note(gettext('Deleted tag %s.') % tag_name)
5488
note('Deleted tag %s.' % tag_name)
5983
5491
if len(revision) != 1:
5984
raise errors.BzrCommandError(gettext(
5492
raise errors.BzrCommandError(
5985
5493
"Tags can only be placed on a single revision, "
5987
5495
revision_id = revision[0].as_revision_id(branch)
5989
5497
revision_id = branch.last_revision()
5990
5498
if tag_name is None:
5991
5499
tag_name = branch.automatic_tag_name(revision_id)
5992
5500
if tag_name is None:
5993
raise errors.BzrCommandError(gettext(
5994
"Please specify a tag name."))
5996
existing_target = branch.tags.lookup_tag(tag_name)
5997
except errors.NoSuchTag:
5998
existing_target = None
5999
if not force and existing_target not in (None, revision_id):
5501
raise errors.BzrCommandError(
5502
"Please specify a tag name.")
5503
if (not force) and branch.tags.has_tag(tag_name):
6000
5504
raise errors.TagAlreadyExists(tag_name)
6001
if existing_target == revision_id:
6002
note(gettext('Tag %s already exists for that revision.') % tag_name)
6004
branch.tags.set_tag(tag_name, revision_id)
6005
if existing_target is None:
6006
note(gettext('Created tag %s.') % tag_name)
6008
note(gettext('Updated tag %s.') % tag_name)
5505
branch.tags.set_tag(tag_name, revision_id)
5506
note('Created tag %s.' % tag_name)
6011
5509
class cmd_tags(Command):
6060
5560
for tag, revspec in tags:
6061
5561
self.outf.write('%-20s %s\n' % (tag, revspec))
6063
def _tags_for_range(self, branch, revision):
6065
rev1, rev2 = _get_revision_range(revision, branch, self.name())
6066
revid1, revid2 = rev1.rev_id, rev2.rev_id
6067
# _get_revision_range will always set revid2 if it's not specified.
6068
# If revid1 is None, it means we want to start from the branch
6069
# origin which is always a valid ancestor. If revid1 == revid2, the
6070
# ancestry check is useless.
6071
if revid1 and revid1 != revid2:
6072
# FIXME: We really want to use the same graph than
6073
# branch.iter_merge_sorted_revisions below, but this is not
6074
# easily available -- vila 2011-09-23
6075
if branch.repository.get_graph().is_ancestor(revid2, revid1):
6076
# We don't want to output anything in this case...
6078
# only show revisions between revid1 and revid2 (inclusive)
6079
tagged_revids = branch.tags.get_reverse_tag_dict()
6081
for r in branch.iter_merge_sorted_revisions(
6082
start_revision_id=revid2, stop_revision_id=revid1,
6083
stop_rule='include'):
6084
revid_tags = tagged_revids.get(r[0], None)
6086
found.extend([(tag, r[0]) for tag in revid_tags])
6090
5564
class cmd_reconfigure(Command):
6091
5565
__doc__ = """Reconfigure the type of a bzr directory.
6105
5579
takes_args = ['location?']
6106
5580
takes_options = [
6107
5581
RegistryOption.from_kwargs(
6110
help='The relation between branch and tree.',
5583
title='Target type',
5584
help='The type to reconfigure the directory to.',
6111
5585
value_switches=True, enum_switch=False,
6112
5586
branch='Reconfigure to be an unbound branch with no working tree.',
6113
5587
tree='Reconfigure to be an unbound branch with a working tree.',
6114
5588
checkout='Reconfigure to be a bound branch with a working tree.',
6115
5589
lightweight_checkout='Reconfigure to be a lightweight'
6116
5590
' checkout (with no local history).',
6118
RegistryOption.from_kwargs(
6120
title='Repository type',
6121
help='Location fo the repository.',
6122
value_switches=True, enum_switch=False,
6123
5591
standalone='Reconfigure to be a standalone branch '
6124
5592
'(i.e. stop using shared repository).',
6125
5593
use_shared='Reconfigure to use a shared repository.',
6127
RegistryOption.from_kwargs(
6129
title='Trees in Repository',
6130
help='Whether new branches in the repository have trees.',
6131
value_switches=True, enum_switch=False,
6132
5594
with_trees='Reconfigure repository to create '
6133
5595
'working trees on branches by default.',
6134
5596
with_no_trees='Reconfigure repository to not create '
6161
5623
# At the moment you can use --stacked-on and a different
6162
5624
# reconfiguration shape at the same time; there seems no good reason
6164
if (tree_type is None and
6165
repository_type is None and
6166
repository_trees is None):
5626
if target_type is None:
6167
5627
if stacked_on or unstacked:
6170
raise errors.BzrCommandError(gettext('No target configuration '
6172
reconfiguration = None
6173
if tree_type == 'branch':
5630
raise errors.BzrCommandError('No target configuration '
5632
elif target_type == 'branch':
6174
5633
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6175
elif tree_type == 'tree':
5634
elif target_type == 'tree':
6176
5635
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
6177
elif tree_type == 'checkout':
5636
elif target_type == 'checkout':
6178
5637
reconfiguration = reconfigure.Reconfigure.to_checkout(
6179
5638
directory, bind_to)
6180
elif tree_type == 'lightweight-checkout':
5639
elif target_type == 'lightweight-checkout':
6181
5640
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
6182
5641
directory, bind_to)
6184
reconfiguration.apply(force)
6185
reconfiguration = None
6186
if repository_type == 'use-shared':
5642
elif target_type == 'use-shared':
6187
5643
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
6188
elif repository_type == 'standalone':
5644
elif target_type == 'standalone':
6189
5645
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
6191
reconfiguration.apply(force)
6192
reconfiguration = None
6193
if repository_trees == 'with-trees':
5646
elif target_type == 'with-trees':
6194
5647
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6195
5648
directory, True)
6196
elif repository_trees == 'with-no-trees':
5649
elif target_type == 'with-no-trees':
6197
5650
reconfiguration = reconfigure.Reconfigure.set_repository_trees(
6198
5651
directory, False)
6200
reconfiguration.apply(force)
6201
reconfiguration = None
5652
reconfiguration.apply(force)
6204
5655
class cmd_switch(Command):
6232
5683
Option('create-branch', short_name='b',
6233
5684
help='Create the target branch from this one before'
6234
5685
' switching to it.'),
6236
help='Store and restore uncommitted changes in the'
6240
5688
def run(self, to_location=None, force=False, create_branch=False,
6241
revision=None, directory=u'.', store=False):
5689
revision=None, directory=u'.'):
6242
5690
from bzrlib import switch
6243
5691
tree_location = directory
6244
5692
revision = _get_one_revision('switch', revision)
6245
possible_transports = []
6246
control_dir = controldir.ControlDir.open_containing(tree_location,
6247
possible_transports=possible_transports)[0]
5693
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
6248
5694
if to_location is None:
6249
5695
if revision is None:
6250
raise errors.BzrCommandError(gettext('You must supply either a'
6251
' revision or a location'))
5696
raise errors.BzrCommandError('You must supply either a'
5697
' revision or a location')
6252
5698
to_location = tree_location
6254
branch = control_dir.open_branch(
6255
possible_transports=possible_transports)
5700
branch = control_dir.open_branch()
6256
5701
had_explicit_nick = branch.get_config().has_explicit_nickname()
6257
5702
except errors.NotBranchError:
6259
5704
had_explicit_nick = False
6260
5705
if create_branch:
6261
5706
if branch is None:
6262
raise errors.BzrCommandError(
6263
gettext('cannot create branch without source branch'))
6264
to_location = lookup_new_sibling_branch(control_dir, to_location,
6265
possible_transports=possible_transports)
5707
raise errors.BzrCommandError('cannot create branch without'
5709
to_location = directory_service.directories.dereference(
5711
if '/' not in to_location and '\\' not in to_location:
5712
# This path is meant to be relative to the existing branch
5713
this_url = self._get_branch_location(control_dir)
5714
to_location = urlutils.join(this_url, '..', to_location)
6266
5715
to_branch = branch.bzrdir.sprout(to_location,
6267
possible_transports=possible_transports,
6268
source_branch=branch).open_branch()
5716
possible_transports=[branch.bzrdir.root_transport],
5717
source_branch=branch).open_branch()
6271
to_branch = Branch.open(to_location,
6272
possible_transports=possible_transports)
5720
to_branch = Branch.open(to_location)
6273
5721
except errors.NotBranchError:
6274
to_branch = open_sibling_branch(control_dir, to_location,
6275
possible_transports=possible_transports)
5722
this_url = self._get_branch_location(control_dir)
5723
to_branch = Branch.open(
5724
urlutils.join(this_url, '..', to_location))
6276
5725
if revision is not None:
6277
5726
revision = revision.as_revision_id(to_branch)
6278
switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
store_uncommitted=store)
5727
switch.switch(control_dir, to_branch, force, revision_id=revision)
6280
5728
if had_explicit_nick:
6281
5729
branch = control_dir.open_branch() #get the new branch!
6282
5730
branch.nick = to_branch.nick
6283
note(gettext('Switched to branch: %s'),
5731
note('Switched to branch: %s',
6284
5732
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5734
def _get_branch_location(self, control_dir):
5735
"""Return location of branch for this control dir."""
5737
this_branch = control_dir.open_branch()
5738
# This may be a heavy checkout, where we want the master branch
5739
master_location = this_branch.get_bound_location()
5740
if master_location is not None:
5741
return master_location
5742
# If not, use a local sibling
5743
return this_branch.base
5744
except errors.NotBranchError:
5745
format = control_dir.find_branch_format()
5746
if getattr(format, 'get_reference', None) is not None:
5747
return format.get_reference(control_dir)
5749
return control_dir.root_transport.base
6288
5752
class cmd_view(Command):
6379
5843
name = current_view
6382
raise errors.BzrCommandError(gettext(
6383
"Both --delete and a file list specified"))
5846
raise errors.BzrCommandError(
5847
"Both --delete and a file list specified")
6385
raise errors.BzrCommandError(gettext(
6386
"Both --delete and --switch specified"))
5849
raise errors.BzrCommandError(
5850
"Both --delete and --switch specified")
6388
5852
tree.views.set_view_info(None, {})
6389
self.outf.write(gettext("Deleted all views.\n"))
5853
self.outf.write("Deleted all views.\n")
6390
5854
elif name is None:
6391
raise errors.BzrCommandError(gettext("No current view to delete"))
5855
raise errors.BzrCommandError("No current view to delete")
6393
5857
tree.views.delete_view(name)
6394
self.outf.write(gettext("Deleted '%s' view.\n") % name)
5858
self.outf.write("Deleted '%s' view.\n" % name)
6397
raise errors.BzrCommandError(gettext(
6398
"Both --switch and a file list specified"))
5861
raise errors.BzrCommandError(
5862
"Both --switch and a file list specified")
6400
raise errors.BzrCommandError(gettext(
6401
"Both --switch and --all specified"))
5864
raise errors.BzrCommandError(
5865
"Both --switch and --all specified")
6402
5866
elif switch == 'off':
6403
5867
if current_view is None:
6404
raise errors.BzrCommandError(gettext("No current view to disable"))
5868
raise errors.BzrCommandError("No current view to disable")
6405
5869
tree.views.set_view_info(None, view_dict)
6406
self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
5870
self.outf.write("Disabled '%s' view.\n" % (current_view))
6408
5872
tree.views.set_view_info(switch, view_dict)
6409
5873
view_str = views.view_display_str(tree.views.lookup_view())
6410
self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
5874
self.outf.write("Using '%s' view: %s\n" % (switch, view_str))
6413
self.outf.write(gettext('Views defined:\n'))
5877
self.outf.write('Views defined:\n')
6414
5878
for view in sorted(view_dict):
6415
5879
if view == current_view:
6419
5883
view_str = views.view_display_str(view_dict[view])
6420
5884
self.outf.write('%s %-20s %s\n' % (active, view, view_str))
6422
self.outf.write(gettext('No views defined.\n'))
5886
self.outf.write('No views defined.\n')
6423
5887
elif file_list:
6424
5888
if name is None:
6425
5889
# No name given and no current view set
6427
5891
elif name == 'off':
6428
raise errors.BzrCommandError(gettext(
6429
"Cannot change the 'off' pseudo view"))
5892
raise errors.BzrCommandError(
5893
"Cannot change the 'off' pseudo view")
6430
5894
tree.views.set_view(name, sorted(file_list))
6431
5895
view_str = views.view_display_str(tree.views.lookup_view())
6432
self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
5896
self.outf.write("Using '%s' view: %s\n" % (name, view_str))
6434
5898
# list the files
6435
5899
if name is None:
6436
5900
# No name given and no current view set
6437
self.outf.write(gettext('No current view.\n'))
5901
self.outf.write('No current view.\n')
6439
5903
view_str = views.view_display_str(tree.views.lookup_view(name))
6440
self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
5904
self.outf.write("'%s' view is: %s\n" % (name, view_str))
6443
5907
class cmd_hooks(Command):
6727
6163
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6728
6164
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6729
6165
('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
('cmd_ping', [], 'bzrlib.smart.ping'),
6731
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6732
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6166
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6733
6167
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6735
6169
builtin_command_registry.register_lazy(name, aliases, module_name)