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):
750
799
if len(names_list) < 2:
751
800
raise errors.BzrCommandError("missing file argument")
752
801
tree, rel_names = tree_files(names_list, canonicalize=False)
802
tree.lock_tree_write()
755
804
self._run(tree, names_list, rel_names, after)
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)
1044
1093
if directory is None:
1045
1094
directory = '.'
1046
1095
# Get the source branch
1047
tree, br_from = bzrdir.BzrDir.open_tree_or_branch(directory)
1097
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1048
1098
if strict is None:
1049
strict = br_from.get_config().get_user_option('push_strict')
1050
if strict is not None:
1051
# FIXME: This should be better supported by config
1053
bools = dict(yes=True, no=False, on=True, off=False,
1054
true=True, false=False)
1056
strict = bools[strict.lower()]
1060
changes = tree.changes_from(tree.basis_tree())
1061
if changes.has_changed():
1062
raise errors.UncommittedChanges(tree)
1099
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1100
if strict is None: strict = True # default value
1063
1101
# Get the tip's revision_id
1064
1102
revision = _get_one_revision('push', revision)
1065
1103
if revision is not None:
1066
1104
revision_id = revision.in_history(br_from).rev_id
1068
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.')
1070
1119
# Get the stacked_on branch, if any
1071
1120
if stacked_on is not None:
1129
1178
'branch for all operations.'),
1130
1179
Option('standalone',
1131
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.'),
1133
1187
aliases = ['get', 'clone']
1135
1189
def run(self, from_location, to_location=None, revision=None,
1136
hardlink=False, stacked=False, standalone=False, no_tree=False):
1190
hardlink=False, stacked=False, standalone=False, no_tree=False,
1191
use_existing_dir=False):
1137
1192
from bzrlib.tag import _merge_tags_if_possible
1139
1194
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1158
1213
to_transport.mkdir('.')
1159
1214
except errors.FileExists:
1160
raise errors.BzrCommandError('Target directory "%s" already'
1161
' 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)
1162
1225
except errors.NoSuchFile:
1163
1226
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1409
1472
title='Deletion Strategy', value_switches=True, enum_switch=False,
1410
1473
safe='Only delete files if they can be'
1411
1474
' safely recovered (default).',
1412
keep="Don't delete any files.",
1475
keep='Delete from bzr but leave the working copy.',
1413
1476
force='Delete all the specified files, even if they can not be '
1414
1477
'recovered and even if they are non-empty directories.')]
1415
1478
aliases = ['rm', 'del']
2997
3060
The working tree and branch checks will only give output if a problem is
2998
3061
detected. The output fields of the repository check are:
3000
revisions: This is just the number of revisions checked. It doesn't
3002
versionedfiles: This is just the number of versionedfiles checked. It
3003
doesn't indicate a problem.
3004
unreferenced ancestors: Texts that are ancestors of other texts, but
3005
are not properly referenced by the revision ancestry. This is a
3006
subtle problem that Bazaar can work around.
3007
unique file texts: This is the total number of unique file contents
3008
seen in the checked revisions. It does not indicate a problem.
3009
repeated file texts: This is the total number of repeated texts seen
3010
in the checked revisions. Texts can be repeated when their file
3011
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
3014
3086
If no restrictions are specified, all Bazaar data that is found at the given
3015
3087
location will be checked.
3492
3564
merge refuses to run if there are any uncommitted changes, unless
3493
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".
3496
3571
To merge the latest revision from bzr.dev::
3535
3610
short_name='d',
3538
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.',
3541
3619
def run(self, location=None, revision=None, force=False,
3560
3639
except errors.NoSuchRevision:
3561
3640
basis_tree = tree.basis_tree()
3563
changes = tree.changes_from(basis_tree)
3564
if changes.has_changed():
3642
if tree.has_changes(basis_tree):
3565
3643
raise errors.UncommittedChanges(tree)
3567
3645
view_info = _get_view_info_for_change_reporter(tree)
3594
3672
if revision is not None and len(revision) > 0:
3595
3673
raise errors.BzrCommandError('Cannot use --uncommitted and'
3596
3674
' --revision at the same time.')
3597
location = self._select_branch_location(tree, location)[0]
3598
other_tree, other_path = WorkingTree.open_containing(location)
3599
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3675
merger = self.get_merger_from_uncommitted(tree, location, pb,
3601
3677
allow_pending = False
3602
if other_path != '':
3603
merger.interesting_files = [other_path]
3605
3679
if merger is None:
3606
3680
merger, allow_pending = self._get_merger_from_branch(tree,
3625
3699
merger.check_basis(False)
3627
return self._do_preview(merger)
3701
return self._do_preview(merger, cleanups)
3703
return self._do_interactive(merger, cleanups)
3629
3705
return self._do_merge(merger, change_reporter, allow_pending,
3632
3708
for cleanup in reversed(cleanups):
3635
def _do_preview(self, merger):
3636
from bzrlib.diff import show_diff_trees
3711
def _get_preview(self, merger, cleanups):
3637
3712
tree_merger = merger.make_merger()
3638
3713
tt = tree_merger.make_preview_transform()
3640
result_tree = tt.get_preview_tree()
3641
show_diff_trees(merger.this_tree, result_tree, self.outf,
3642
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='')
3646
3724
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3647
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))
3658
3751
def sanity_check_merger(self, merger):
3659
3752
if (merger.show_base and
3660
3753
not merger.merge_type is _mod_merge.Merge3Merger):
3695
3788
base_branch, base_path = Branch.open_containing(base_loc,
3696
3789
possible_transports)
3697
3790
# Find the revision ids
3698
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:
3699
3799
other_revision_id = _mod_revision.ensure_null(
3700
3800
other_branch.last_revision())
3702
other_revision_id = revision[-1].as_revision_id(other_branch)
3703
if (revision is not None and len(revision) == 2
3704
and revision[0] is not None):
3705
base_revision_id = revision[0].as_revision_id(base_branch)
3707
base_revision_id = None
3708
3801
# Remember where we merge from
3709
3802
if ((remember or tree.branch.get_submit_branch() is None) and
3710
3803
user_location is not None):
3719
3812
allow_pending = True
3720
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]
3722
3831
def _select_branch_location(self, tree, user_location, revision=None,
3724
3833
"""Select a branch location, according to possible inputs.
4877
4986
help='Write merge directive to this file; '
4878
4987
'use - for stdout.',
4990
help='Refuse to send if there are uncommitted changes in'
4991
' the working tree, --no-strict disables the check.'),
4880
4992
Option('mail-to', help='Mail the request to this address.',
4884
4996
Option('body', help='Body for the email.', type=unicode),
4885
4997
RegistryOption('format',
4886
help='Use the specified output format.',
4887
lazy_registry=('bzrlib.send', 'format_registry'))
4998
help='Use the specified output format.',
4999
lazy_registry=('bzrlib.send', 'format_registry')),
4890
5002
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4891
5003
no_patch=False, revision=None, remember=False, output=None,
4892
format=None, mail_to=None, message=None, body=None, **kwargs):
5004
format=None, mail_to=None, message=None, body=None,
5005
strict=None, **kwargs):
4893
5006
from bzrlib.send import send
4894
5007
return send(submit_branch, revision, public_branch, remember,
4895
format, no_bundle, no_patch, output,
4896
kwargs.get('from', '.'), mail_to, message, body,
5008
format, no_bundle, no_patch, output,
5009
kwargs.get('from', '.'), mail_to, message, body,
4900
5014
class cmd_bundle_revisions(cmd_send):
4945
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.'),
4948
5065
RegistryOption('format',
4949
5066
help='Use the specified output format.',
4958
5075
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4959
5076
no_patch=False, revision=None, remember=False, output=None,
4960
format=None, **kwargs):
5077
format=None, strict=None, **kwargs):
4961
5078
if output is None:
4963
5080
from bzrlib.send import send
4964
5081
return send(submit_branch, revision, public_branch, remember,
4965
5082
format, no_bundle, no_patch, output,
4966
5083
kwargs.get('from', '.'), None, None, None,
5084
self.outf, strict=strict)
4970
5087
class cmd_tag(Command):
5143
5260
Option('bind-to', help='Branch to bind checkout to.', type=str),
5144
5261
Option('force',
5145
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.',
5149
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,
5150
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
5151
5287
if target_type is None:
5152
raise errors.BzrCommandError('No target configuration specified')
5288
if stacked_on or unstacked:
5291
raise errors.BzrCommandError('No target configuration '
5153
5293
elif target_type == 'branch':
5154
5294
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5155
5295
elif target_type == 'tree':
5199
5339
takes_args = ['to_location']
5200
5340
takes_options = [Option('force',
5201
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.'),
5204
def run(self, to_location, force=False):
5347
def run(self, to_location, force=False, create_branch=False):
5205
5348
from bzrlib import switch
5206
5349
tree_location = '.'
5207
5350
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5209
5352
branch = control_dir.open_branch()
5210
5353
had_explicit_nick = branch.get_config().has_explicit_nickname()
5211
5354
except errors.NotBranchError:
5212
5356
had_explicit_nick = False
5214
to_branch = Branch.open(to_location)
5215
except errors.NotBranchError:
5216
this_url = self._get_branch_location(control_dir)
5217
to_branch = Branch.open(
5218
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))
5219
5382
switch.switch(control_dir, to_branch, force)
5220
5383
if had_explicit_nick:
5221
5384
branch = control_dir.open_branch() #get the new branch!