450
449
except errors.NoWorkingTree:
451
450
raise errors.BzrCommandError("No working tree to remove")
452
451
except errors.NotLocalUrl:
453
raise errors.BzrCommandError("You cannot remove the working tree of a "
452
raise errors.BzrCommandError("You cannot remove the working tree"
456
changes = working.changes_from(working.basis_tree())
457
if changes.has_changed():
455
# XXX: What about pending merges ? -- vila 20090629
456
if working.has_changes(working.basis_tree()):
458
457
raise errors.UncommittedChanges(working)
460
459
working_path = working.bzrdir.root_transport.base
461
460
branch_path = working.branch.bzrdir.root_transport.base
462
461
if working_path != branch_path:
463
raise errors.BzrCommandError("You cannot remove the working tree from "
464
"a lightweight checkout")
462
raise errors.BzrCommandError("You cannot remove the working tree"
463
" from a lightweight checkout")
466
465
d.destroy_workingtree()
475
474
_see_also = ['info']
476
475
takes_args = ['location?']
477
Option('tree', help='Show revno of working tree'),
479
def run(self, location=u'.'):
480
self.outf.write(str(Branch.open_containing(location)[0].revno()))
481
self.outf.write('\n')
481
def run(self, tree=False, location=u'.'):
484
wt = WorkingTree.open_containing(location)[0]
486
except (errors.NoWorkingTree, errors.NotLocalUrl):
487
raise errors.NoWorkingTree(location)
489
revid = wt.last_revision()
491
revno_t = wt.branch.revision_id_to_dotted_revno(revid)
492
except errors.NoSuchRevision:
494
revno = ".".join(str(n) for n in revno_t)
498
b = Branch.open_containing(location)[0]
505
self.outf.write(str(revno) + '\n')
484
508
class cmd_revision_info(Command):
521
Option('tree', help='Show revno of working tree'),
500
def run(self, revision=None, directory=u'.', revision_info_list=[]):
503
if revision is not None:
504
revs.extend(revision)
505
if revision_info_list is not None:
506
for rev in revision_info_list:
507
revs.append(RevisionSpec.from_string(rev))
509
b = Branch.open_containing(directory)[0]
512
revs.append(RevisionSpec.from_string('-1'))
515
revision_id = rev.as_revision_id(b)
517
revno = '%4d' % (b.revision_id_to_revno(revision_id))
518
except errors.NoSuchRevision:
519
dotted_map = b.get_revision_id_to_revno_map()
520
revno = '.'.join(str(i) for i in dotted_map[revision_id])
521
print '%s %s' % (revno, revision_id)
525
def run(self, revision=None, directory=u'.', tree=False,
526
revision_info_list=[]):
529
wt = WorkingTree.open_containing(directory)[0]
532
except (errors.NoWorkingTree, errors.NotLocalUrl):
534
b = Branch.open_containing(directory)[0]
538
if revision is not None:
539
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
540
if revision_info_list is not None:
541
for rev_str in revision_info_list:
542
rev_spec = RevisionSpec.from_string(rev_str)
543
revision_ids.append(rev_spec.as_revision_id(b))
544
# No arguments supplied, default to the last revision
545
if len(revision_ids) == 0:
548
raise errors.NoWorkingTree(directory)
549
revision_ids.append(wt.last_revision())
551
revision_ids.append(b.last_revision())
555
for revision_id in revision_ids:
557
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
558
revno = '.'.join(str(i) for i in dotted_revno)
559
except errors.NoSuchRevision:
561
maxlen = max(maxlen, len(revno))
562
revinfos.append([revno, revision_id])
570
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
524
573
class cmd_add(Command):
764
813
raise errors.BzrCommandError('--after cannot be specified with'
766
815
work_tree, file_list = tree_files(names_list, default_branch='.')
767
work_tree.lock_write()
816
work_tree.lock_tree_write()
769
818
rename_map.RenameMap.guess_renames(work_tree, dry_run)
946
995
if branch_to.get_parent() is None or remember:
947
996
branch_to.set_parent(branch_from.base)
949
if revision is not None:
950
revision_id = revision.as_revision_id(branch_from)
952
branch_to.lock_write()
998
if branch_from is not branch_to:
999
branch_from.lock_read()
954
if tree_to is not None:
955
view_info = _get_view_info_for_change_reporter(tree_to)
956
change_reporter = delta._ChangeReporter(
957
unversioned_filter=tree_to.is_ignored, view_info=view_info)
958
result = tree_to.pull(branch_from, overwrite, revision_id,
960
possible_transports=possible_transports,
963
result = branch_to.pull(branch_from, overwrite, revision_id,
966
result.report(self.outf)
967
if verbose and result.old_revid != result.new_revid:
968
log.show_branch_change(branch_to, self.outf, result.old_revno,
1001
if revision is not None:
1002
revision_id = revision.as_revision_id(branch_from)
1004
branch_to.lock_write()
1006
if tree_to is not None:
1007
view_info = _get_view_info_for_change_reporter(tree_to)
1008
change_reporter = delta._ChangeReporter(
1009
unversioned_filter=tree_to.is_ignored,
1010
view_info=view_info)
1011
result = tree_to.pull(
1012
branch_from, overwrite, revision_id, change_reporter,
1013
possible_transports=possible_transports, local=local)
1015
result = branch_to.pull(
1016
branch_from, overwrite, revision_id, local=local)
1018
result.report(self.outf)
1019
if verbose and result.old_revid != result.new_revid:
1020
log.show_branch_change(
1021
branch_to, self.outf, result.old_revno,
1026
if branch_from is not branch_to:
1027
branch_from.unlock()
974
1030
class cmd_push(Command):
1021
1077
'for the commit history. Only the work not present in the '
1022
1078
'referenced branch is included in the branch created.',
1081
help='Refuse to push if there are uncommitted changes in'
1082
' the working tree, --no-strict disables the check.'),
1025
1084
takes_args = ['location?']
1026
1085
encoding_type = 'replace'
1028
1087
def run(self, location=None, remember=False, overwrite=False,
1029
1088
create_prefix=False, verbose=False, revision=None,
1030
1089
use_existing_dir=False, directory=None, stacked_on=None,
1090
stacked=False, strict=None):
1032
1091
from bzrlib.push import _show_push_branch
1034
# Get the source branch and revision_id
1035
1093
if directory is None:
1036
1094
directory = '.'
1037
br_from = Branch.open_containing(directory)[0]
1095
# Get the source branch
1097
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1099
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1100
if strict is None: strict = True # default value
1101
# Get the tip's revision_id
1038
1102
revision = _get_one_revision('push', revision)
1039
1103
if revision is not None:
1040
1104
revision_id = revision.in_history(br_from).rev_id
1042
1106
revision_id = None
1107
if strict and tree is not None and revision_id is None:
1108
if (tree.has_changes(tree.basis_tree())
1109
or len(tree.get_parent_ids()) > 1):
1110
raise errors.UncommittedChanges(
1111
tree, more='Use --no-strict to force the push.')
1112
if tree.last_revision() != tree.branch.last_revision():
1113
# The tree has lost sync with its branch, there is little
1114
# chance that the user is aware of it but he can still force
1115
# the push with --no-strict
1116
raise errors.OutOfDateTree(
1117
tree, more='Use --no-strict to force the push.')
1044
1119
# Get the stacked_on branch, if any
1045
1120
if stacked_on is not None:
1080
1155
class cmd_branch(Command):
1081
"""Create a new copy of a branch.
1156
"""Create a new branch that is a copy of an existing branch.
1083
1158
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1084
1159
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1103
1178
'branch for all operations.'),
1104
1179
Option('standalone',
1105
1180
help='Do not use a shared repository, even if available.'),
1181
Option('use-existing-dir',
1182
help='By default branch will fail if the target'
1183
' directory exists, but does not already'
1184
' have a control directory. This flag will'
1185
' allow branch to proceed.'),
1107
1187
aliases = ['get', 'clone']
1109
1189
def run(self, from_location, to_location=None, revision=None,
1110
hardlink=False, stacked=False, standalone=False, no_tree=False):
1190
hardlink=False, stacked=False, standalone=False, no_tree=False,
1191
use_existing_dir=False):
1111
1192
from bzrlib.tag import _merge_tags_if_possible
1113
1194
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1196
if (accelerator_tree is not None and
1197
accelerator_tree.supports_content_filtering()):
1198
accelerator_tree = None
1115
1199
revision = _get_one_revision('branch', revision)
1116
1200
br_from.lock_read()
1129
1213
to_transport.mkdir('.')
1130
1214
except errors.FileExists:
1131
raise errors.BzrCommandError('Target directory "%s" already'
1132
' exists.' % to_location)
1215
if not use_existing_dir:
1216
raise errors.BzrCommandError('Target directory "%s" '
1217
'already exists.' % to_location)
1220
bzrdir.BzrDir.open_from_transport(to_transport)
1221
except errors.NotBranchError:
1224
raise errors.AlreadyBranchError(to_location)
1133
1225
except errors.NoSuchFile:
1134
1226
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1380
1472
title='Deletion Strategy', value_switches=True, enum_switch=False,
1381
1473
safe='Only delete files if they can be'
1382
1474
' safely recovered (default).',
1383
keep="Don't delete any files.",
1475
keep='Delete from bzr but leave the working copy.',
1384
1476
force='Delete all the specified files, even if they can not be '
1385
1477
'recovered and even if they are non-empty directories.')]
1386
1478
aliases = ['rm', 'del']
1621
1713
branch.set_append_revisions_only(True)
1622
1714
except errors.UpgradeRequired:
1623
1715
raise errors.BzrCommandError('This branch format cannot be set'
1624
' to append-revisions-only. Try --experimental-branch6')
1716
' to append-revisions-only. Try --default.')
1625
1717
if not is_quiet():
1626
1718
from bzrlib.info import describe_layout, describe_format
2367
2459
if path is None:
2372
2463
raise errors.BzrCommandError('cannot specify both --from-root'
2376
2466
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
2469
# Calculate the prefix to use
2473
prefix = relpath + '/'
2474
elif fs_path != '.':
2475
prefix = fs_path + '/'
2382
2477
if revision is not None or tree is None:
2383
2478
tree = _get_one_revision_tree('ls', revision, branch=branch)
2393
2488
tree.lock_read()
2395
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2396
if fp.startswith(relpath):
2397
rp = fp[len(relpath):]
2398
fp = osutils.pathjoin(prefix, rp)
2399
if not recursive and '/' in rp:
2401
if not all and not selection[fc]:
2403
if kind is not None and fkind != kind:
2407
views.check_path_in_view(tree, fp)
2408
except errors.FileOutsideView:
2410
kindch = entry.kind_character()
2411
outstring = fp + kindch
2412
ui.ui_factory.clear_term()
2414
outstring = '%-8s %s' % (fc, outstring)
2415
if show_ids and fid is not None:
2416
outstring = "%-50s %s" % (outstring, fid)
2417
self.outf.write(outstring + '\n')
2419
self.outf.write(fp + '\0')
2422
self.outf.write(fid)
2423
self.outf.write('\0')
2490
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2491
from_dir=relpath, recursive=recursive):
2492
# Apply additional masking
2493
if not all and not selection[fc]:
2495
if kind is not None and fkind != kind:
2500
fullpath = osutils.pathjoin(relpath, fp)
2503
views.check_path_in_view(tree, fullpath)
2504
except errors.FileOutsideView:
2509
fp = osutils.pathjoin(prefix, fp)
2510
kindch = entry.kind_character()
2511
outstring = fp + kindch
2512
ui.ui_factory.clear_term()
2514
outstring = '%-8s %s' % (fc, outstring)
2515
if show_ids and fid is not None:
2516
outstring = "%-50s %s" % (outstring, fid)
2517
self.outf.write(outstring + '\n')
2519
self.outf.write(fp + '\0')
2522
self.outf.write(fid)
2523
self.outf.write('\0')
2426
2527
if fid is not None:
2431
self.outf.write('%-50s %s\n' % (outstring, my_id))
2433
self.outf.write(outstring + '\n')
2531
self.outf.write('%-50s %s\n' % (outstring, my_id))
2533
self.outf.write(outstring + '\n')
2960
3060
The working tree and branch checks will only give output if a problem is
2961
3061
detected. The output fields of the repository check are:
2963
revisions: This is just the number of revisions checked. It doesn't
2965
versionedfiles: This is just the number of versionedfiles checked. It
2966
doesn't indicate a problem.
2967
unreferenced ancestors: Texts that are ancestors of other texts, but
2968
are not properly referenced by the revision ancestry. This is a
2969
subtle problem that Bazaar can work around.
2970
unique file texts: This is the total number of unique file contents
2971
seen in the checked revisions. It does not indicate a problem.
2972
repeated file texts: This is the total number of repeated texts seen
2973
in the checked revisions. Texts can be repeated when their file
2974
entries are modified, but the file contents are not. It does not
3064
This is just the number of revisions checked. It doesn't
3068
This is just the number of versionedfiles checked. It
3069
doesn't indicate a problem.
3071
unreferenced ancestors
3072
Texts that are ancestors of other texts, but
3073
are not properly referenced by the revision ancestry. This is a
3074
subtle problem that Bazaar can work around.
3077
This is the total number of unique file contents
3078
seen in the checked revisions. It does not indicate a problem.
3081
This is the total number of repeated texts seen
3082
in the checked revisions. Texts can be repeated when their file
3083
entries are modified, but the file contents are not. It does not
2977
3086
If no restrictions are specified, all Bazaar data that is found at the given
2978
3087
location will be checked.
3455
3564
merge refuses to run if there are any uncommitted changes, unless
3456
3565
--force is given.
3567
To select only some changes to merge, use "merge -i", which will prompt
3568
you to apply each diff hunk and file change, similar to "shelve".
3459
3571
To merge the latest revision from bzr.dev::
3498
3610
short_name='d',
3501
Option('preview', help='Instead of merging, show a diff of the merge.')
3613
Option('preview', help='Instead of merging, show a diff of the'
3615
Option('interactive', help='Select changes interactively.',
3504
3619
def run(self, location=None, revision=None, force=False,
3523
3639
except errors.NoSuchRevision:
3524
3640
basis_tree = tree.basis_tree()
3526
changes = tree.changes_from(basis_tree)
3527
if changes.has_changed():
3642
if tree.has_changes(basis_tree):
3528
3643
raise errors.UncommittedChanges(tree)
3530
3645
view_info = _get_view_info_for_change_reporter(tree)
3557
3672
if revision is not None and len(revision) > 0:
3558
3673
raise errors.BzrCommandError('Cannot use --uncommitted and'
3559
3674
' --revision at the same time.')
3560
location = self._select_branch_location(tree, location)[0]
3561
other_tree, other_path = WorkingTree.open_containing(location)
3562
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3675
merger = self.get_merger_from_uncommitted(tree, location, pb,
3564
3677
allow_pending = False
3565
if other_path != '':
3566
merger.interesting_files = [other_path]
3568
3679
if merger is None:
3569
3680
merger, allow_pending = self._get_merger_from_branch(tree,
3588
3699
merger.check_basis(False)
3590
return self._do_preview(merger)
3701
return self._do_preview(merger, cleanups)
3703
return self._do_interactive(merger, cleanups)
3592
3705
return self._do_merge(merger, change_reporter, allow_pending,
3595
3708
for cleanup in reversed(cleanups):
3598
def _do_preview(self, merger):
3599
from bzrlib.diff import show_diff_trees
3711
def _get_preview(self, merger, cleanups):
3600
3712
tree_merger = merger.make_merger()
3601
3713
tt = tree_merger.make_preview_transform()
3603
result_tree = tt.get_preview_tree()
3604
show_diff_trees(merger.this_tree, result_tree, self.outf,
3605
old_label='', new_label='')
3714
cleanups.append(tt.finalize)
3715
result_tree = tt.get_preview_tree()
3718
def _do_preview(self, merger, cleanups):
3719
from bzrlib.diff import show_diff_trees
3720
result_tree = self._get_preview(merger, cleanups)
3721
show_diff_trees(merger.this_tree, result_tree, self.outf,
3722
old_label='', new_label='')
3609
3724
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3610
3725
merger.change_reporter = change_reporter
3736
def _do_interactive(self, merger, cleanups):
3737
"""Perform an interactive merge.
3739
This works by generating a preview tree of the merge, then using
3740
Shelver to selectively remove the differences between the working tree
3741
and the preview tree.
3743
from bzrlib import shelf_ui
3744
result_tree = self._get_preview(merger, cleanups)
3745
writer = bzrlib.option.diff_writer_registry.get()
3746
shelver = shelf_ui.Shelver(merger.this_tree, result_tree, destroy=True,
3747
reporter=shelf_ui.ApplyReporter(),
3748
diff_writer=writer(sys.stdout))
3621
3751
def sanity_check_merger(self, merger):
3622
3752
if (merger.show_base and
3623
3753
not merger.merge_type is _mod_merge.Merge3Merger):
3658
3788
base_branch, base_path = Branch.open_containing(base_loc,
3659
3789
possible_transports)
3660
3790
# Find the revision ids
3661
if revision is None or len(revision) < 1 or revision[-1] is None:
3791
other_revision_id = None
3792
base_revision_id = None
3793
if revision is not None:
3794
if len(revision) >= 1:
3795
other_revision_id = revision[-1].as_revision_id(other_branch)
3796
if len(revision) == 2:
3797
base_revision_id = revision[0].as_revision_id(base_branch)
3798
if other_revision_id is None:
3662
3799
other_revision_id = _mod_revision.ensure_null(
3663
3800
other_branch.last_revision())
3665
other_revision_id = revision[-1].as_revision_id(other_branch)
3666
if (revision is not None and len(revision) == 2
3667
and revision[0] is not None):
3668
base_revision_id = revision[0].as_revision_id(base_branch)
3670
base_revision_id = None
3671
3801
# Remember where we merge from
3672
3802
if ((remember or tree.branch.get_submit_branch() is None) and
3673
3803
user_location is not None):
3682
3812
allow_pending = True
3683
3813
return merger, allow_pending
3815
def get_merger_from_uncommitted(self, tree, location, pb, cleanups):
3816
"""Get a merger for uncommitted changes.
3818
:param tree: The tree the merger should apply to.
3819
:param location: The location containing uncommitted changes.
3820
:param pb: The progress bar to use for showing progress.
3821
:param cleanups: A list of operations to perform to clean up the
3822
temporary directories, unfinalized objects, etc.
3824
location = self._select_branch_location(tree, location)[0]
3825
other_tree, other_path = WorkingTree.open_containing(location)
3826
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree, pb)
3827
if other_path != '':
3828
merger.interesting_files = [other_path]
3685
3831
def _select_branch_location(self, tree, user_location, revision=None,
3687
3833
"""Select a branch location, according to possible inputs.
4840
4986
help='Write merge directive to this file; '
4841
4987
'use - for stdout.',
4990
help='Refuse to send if there are uncommitted changes in'
4991
' the working tree, --no-strict disables the check.'),
4843
4992
Option('mail-to', help='Mail the request to this address.',
4847
4996
Option('body', help='Body for the email.', type=unicode),
4848
4997
RegistryOption('format',
4849
help='Use the specified output format.',
4850
lazy_registry=('bzrlib.send', 'format_registry'))
4998
help='Use the specified output format.',
4999
lazy_registry=('bzrlib.send', 'format_registry')),
4853
5002
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4854
5003
no_patch=False, revision=None, remember=False, output=None,
4855
format=None, mail_to=None, message=None, body=None, **kwargs):
5004
format=None, mail_to=None, message=None, body=None,
5005
strict=None, **kwargs):
4856
5006
from bzrlib.send import send
4857
5007
return send(submit_branch, revision, public_branch, remember,
4858
format, no_bundle, no_patch, output,
4859
kwargs.get('from', '.'), mail_to, message, body,
5008
format, no_bundle, no_patch, output,
5009
kwargs.get('from', '.'), mail_to, message, body,
4863
5014
class cmd_bundle_revisions(cmd_send):
4908
5059
Option('output', short_name='o', help='Write directive to this file.',
5062
help='Refuse to bundle revisions if there are uncommitted'
5063
' changes in the working tree, --no-strict disables the check.'),
4911
5065
RegistryOption('format',
4912
5066
help='Use the specified output format.',
4921
5075
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4922
5076
no_patch=False, revision=None, remember=False, output=None,
4923
format=None, **kwargs):
5077
format=None, strict=None, **kwargs):
4924
5078
if output is None:
4926
5080
from bzrlib.send import send
4927
5081
return send(submit_branch, revision, public_branch, remember,
4928
5082
format, no_bundle, no_patch, output,
4929
5083
kwargs.get('from', '.'), None, None, None,
5084
self.outf, strict=strict)
4933
5087
class cmd_tag(Command):
5106
5260
Option('bind-to', help='Branch to bind checkout to.', type=str),
5107
5261
Option('force',
5108
help='Perform reconfiguration even if local changes'
5262
help='Perform reconfiguration even if local changes'
5264
Option('stacked-on',
5265
help='Reconfigure a branch to be stacked on another branch.',
5269
help='Reconfigure a branch to be unstacked. This '
5270
'may require copying substantial data into it.',
5112
def run(self, location=None, target_type=None, bind_to=None, force=False):
5274
def run(self, location=None, target_type=None, bind_to=None, force=False,
5113
5277
directory = bzrdir.BzrDir.open(location)
5278
if stacked_on and unstacked:
5279
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5280
elif stacked_on is not None:
5281
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5283
reconfigure.ReconfigureUnstacked().apply(directory)
5284
# At the moment you can use --stacked-on and a different
5285
# reconfiguration shape at the same time; there seems no good reason
5114
5287
if target_type is None:
5115
raise errors.BzrCommandError('No target configuration specified')
5288
if stacked_on or unstacked:
5291
raise errors.BzrCommandError('No target configuration '
5116
5293
elif target_type == 'branch':
5117
5294
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5118
5295
elif target_type == 'tree':
5162
5339
takes_args = ['to_location']
5163
5340
takes_options = [Option('force',
5164
help='Switch even if local commits will be lost.')
5341
help='Switch even if local commits will be lost.'),
5342
Option('create-branch', short_name='b',
5343
help='Create the target branch from this one before'
5344
' switching to it.'),
5167
def run(self, to_location, force=False):
5347
def run(self, to_location, force=False, create_branch=False):
5168
5348
from bzrlib import switch
5169
5349
tree_location = '.'
5170
5350
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5172
5352
branch = control_dir.open_branch()
5173
5353
had_explicit_nick = branch.get_config().has_explicit_nickname()
5174
5354
except errors.NotBranchError:
5175
5356
had_explicit_nick = False
5177
to_branch = Branch.open(to_location)
5178
except errors.NotBranchError:
5179
this_url = self._get_branch_location(control_dir)
5180
to_branch = Branch.open(
5181
urlutils.join(this_url, '..', to_location))
5359
raise errors.BzrCommandError('cannot create branch without'
5361
if '/' not in to_location and '\\' not in to_location:
5362
# This path is meant to be relative to the existing branch
5363
this_url = self._get_branch_location(control_dir)
5364
to_location = urlutils.join(this_url, '..', to_location)
5365
to_branch = branch.bzrdir.sprout(to_location,
5366
possible_transports=[branch.bzrdir.root_transport],
5367
source_branch=branch).open_branch()
5369
# from_branch = control_dir.open_branch()
5370
# except errors.NotBranchError:
5371
# raise BzrCommandError('Cannot create a branch from this'
5372
# ' location when we cannot open this branch')
5373
# from_branch.bzrdir.sprout(
5377
to_branch = Branch.open(to_location)
5378
except errors.NotBranchError:
5379
this_url = self._get_branch_location(control_dir)
5380
to_branch = Branch.open(
5381
urlutils.join(this_url, '..', to_location))
5182
5382
switch.switch(control_dir, to_branch, force)
5183
5383
if had_explicit_nick:
5184
5384
branch = control_dir.open_branch() #get the new branch!