60
60
from bzrlib.workingtree import WorkingTree
63
from bzrlib.commands import Command, display_command
63
from bzrlib.commands import (
65
builtin_command_registry,
64
68
from bzrlib.option import (
456
460
for node in bt.iter_all_entries():
457
461
# Node is made up of:
458
462
# (index, key, value, [references])
459
refs_as_tuples = static_tuple.as_tuples(node[3])
466
refs_as_tuples = None
468
refs_as_tuples = static_tuple.as_tuples(refs)
460
469
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
461
470
self.outf.write('%s\n' % (as_tuple,))
700
709
def run(self, dir_list):
701
710
for d in dir_list:
703
711
wt, dd = WorkingTree.open_containing(d)
705
self.outf.write('added %s\n' % d)
712
base = os.path.dirname(dd)
713
id = wt.path2id(base)
717
self.outf.write('added %s\n' % d)
719
raise errors.NotVersionedError(path=base)
708
722
class cmd_relpath(Command):
975
989
tree_to = WorkingTree.open_containing(directory)[0]
976
990
branch_to = tree_to.branch
992
self.add_cleanup(tree_to.unlock)
977
993
except errors.NoWorkingTree:
979
995
branch_to = Branch.open_containing(directory)[0]
996
branch_to.lock_write()
997
self.add_cleanup(branch_to.unlock)
981
999
if local and not branch_to.get_bound_location():
982
1000
raise errors.LocalRequiresBoundBranch()
1014
1032
branch_from = Branch.open(location,
1015
1033
possible_transports=possible_transports)
1034
branch_from.lock_read()
1035
self.add_cleanup(branch_from.unlock)
1017
1037
if branch_to.get_parent() is None or remember:
1018
1038
branch_to.set_parent(branch_from.base)
1020
if branch_from is not branch_to:
1021
branch_from.lock_read()
1022
self.add_cleanup(branch_from.unlock)
1023
1040
if revision is not None:
1024
1041
revision_id = revision.as_revision_id(branch_from)
1026
branch_to.lock_write()
1027
self.add_cleanup(branch_to.unlock)
1028
1043
if tree_to is not None:
1029
1044
view_info = _get_view_info_for_change_reporter(tree_to)
1030
1045
change_reporter = delta._ChangeReporter(
1112
1127
# Get the source branch
1113
1128
(tree, br_from,
1114
1129
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1116
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1117
if strict is None: strict = True # default value
1118
1130
# Get the tip's revision_id
1119
1131
revision = _get_one_revision('push', revision)
1120
1132
if revision is not None:
1121
1133
revision_id = revision.in_history(br_from).rev_id
1123
1135
revision_id = None
1124
if strict and tree is not None and revision_id is None:
1125
if (tree.has_changes()):
1126
raise errors.UncommittedChanges(
1127
tree, more='Use --no-strict to force the push.')
1128
if tree.last_revision() != tree.branch.last_revision():
1129
# The tree has lost sync with its branch, there is little
1130
# chance that the user is aware of it but he can still force
1131
# the push with --no-strict
1132
raise errors.OutOfDateTree(
1133
tree, more='Use --no-strict to force the push.')
1136
if tree is not None and revision_id is None:
1137
tree.warn_if_changed_or_out_of_date(
1138
strict, 'push_strict', 'Use --no-strict to force the push.')
1135
1139
# Get the stacked_on branch, if any
1136
1140
if stacked_on is not None:
1137
1141
stacked_on = urlutils.normalize_url(stacked_on)
1418
1422
branch_location = tree.branch.base
1419
1423
self.add_cleanup(tree.unlock)
1420
1424
# get rid of the final '/' and be ready for display
1421
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1425
branch_location = urlutils.unescape_for_display(
1426
branch_location.rstrip('/'),
1423
1428
existing_pending_merges = tree.get_parent_ids()[1:]
1424
1429
if master is None:
1434
1439
revision_id = branch.last_revision()
1435
1440
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1436
revno = branch.revision_id_to_revno(revision_id)
1437
note("Tree is up to date at revision %d of branch %s" %
1438
(revno, branch_location))
1441
revno = branch.revision_id_to_dotted_revno(revision_id)
1442
note("Tree is up to date at revision %s of branch %s" %
1443
('.'.join(map(str, revno)), branch_location))
1440
1445
view_info = _get_view_info_for_change_reporter(tree)
1441
1446
change_reporter = delta._ChangeReporter(
1453
1458
"bzr update --revision only works"
1454
1459
" for a revision in the branch history"
1455
1460
% (e.revision))
1456
revno = tree.branch.revision_id_to_revno(
1461
revno = tree.branch.revision_id_to_dotted_revno(
1457
1462
_mod_revision.ensure_null(tree.last_revision()))
1458
note('Updated to revision %d of branch %s' %
1459
(revno, branch_location))
1463
note('Updated to revision %s of branch %s' %
1464
('.'.join(map(str, revno)), branch_location))
1460
1465
if tree.get_parent_ids()[1:] != existing_pending_merges:
1461
1466
note('Your local commits will now show as pending merges with '
1462
1467
"'bzr status', and can be committed with 'bzr commit'.")
1939
1944
help='Use this command to compare files.',
1947
RegistryOption('format',
1948
help='Diff format to use.',
1949
lazy_registry=('bzrlib.diff', 'format_registry'),
1950
value_switches=False, title='Diff format'),
1943
1952
aliases = ['di', 'dif']
1944
1953
encoding_type = 'exact'
1946
1955
@display_command
1947
1956
def run(self, revision=None, file_list=None, diff_options=None,
1948
prefix=None, old=None, new=None, using=None):
1949
from bzrlib.diff import get_trees_and_branches_to_diff, show_diff_trees
1957
prefix=None, old=None, new=None, using=None, format=None):
1958
from bzrlib.diff import (get_trees_and_branches_to_diff,
1951
1961
if (prefix is None) or (prefix == '0'):
1952
1962
# diff -p0 format
1966
1976
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1967
1977
' one or two revision specifiers')
1979
if using is not None and format is not None:
1980
raise errors.BzrCommandError('--using and --format are mutually '
1969
1983
(old_tree, new_tree,
1970
1984
old_branch, new_branch,
1971
1985
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1974
1988
specific_files=specific_files,
1975
1989
external_diff_options=diff_options,
1976
1990
old_label=old_label, new_label=new_label,
1977
extra_trees=extra_trees, using=using)
1991
extra_trees=extra_trees, using=using,
1980
1995
class cmd_deleted(Command):
2428
2443
raise errors.BzrCommandError(
2429
2444
"bzr %s doesn't accept two revisions in different"
2430
2445
" branches." % command_name)
2431
rev1 = start_spec.in_history(branch)
2446
if start_spec.spec is None:
2447
# Avoid loading all the history.
2448
rev1 = RevisionInfo(branch, None, None)
2450
rev1 = start_spec.in_history(branch)
2432
2451
# Avoid loading all of history when we know a missing
2433
2452
# end of range means the last revision ...
2434
2453
if end_spec.spec is None:
2684
2703
if old_default_rules is not None:
2685
2704
# dump the rules and exit
2686
2705
for pattern in ignores.OLD_DEFAULTS:
2706
self.outf.write("%s\n" % pattern)
2689
2708
if not name_pattern_list:
2690
2709
raise errors.BzrCommandError("ignore requires at least one "
2706
2725
if id is not None:
2707
2726
filename = entry[0]
2708
2727
if ignored.match(filename):
2709
matches.append(filename.encode('utf-8'))
2728
matches.append(filename)
2711
2730
if len(matches) > 0:
2712
print "Warning: the following files are version controlled and" \
2713
" match your ignore pattern:\n%s" \
2714
"\nThese files will continue to be version controlled" \
2715
" unless you 'bzr remove' them." % ("\n".join(matches),)
2731
self.outf.write("Warning: the following files are version controlled and"
2732
" match your ignore pattern:\n%s"
2733
"\nThese files will continue to be version controlled"
2734
" unless you 'bzr remove' them.\n" % ("\n".join(matches),))
2718
2737
class cmd_ignored(Command):
2757
2776
revno = int(revno)
2758
2777
except ValueError:
2759
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2761
print WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2778
raise errors.BzrCommandError("not a valid revision-number: %r"
2780
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2781
self.outf.write("%s\n" % revid)
2764
2784
class cmd_export(Command):
2802
2822
help="Name of the root directory inside the exported file."),
2823
Option('per-file-timestamps',
2824
help='Set modification time of files to that of the last '
2825
'revision in which it was changed.'),
2804
2827
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2805
root=None, filters=False):
2828
root=None, filters=False, per_file_timestamps=False):
2806
2829
from bzrlib.export import export
2808
2831
if branch_or_subdir is None:
2816
2839
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2818
export(rev_tree, dest, format, root, subdir, filtered=filters)
2841
export(rev_tree, dest, format, root, subdir, filtered=filters,
2842
per_file_timestamps=per_file_timestamps)
2819
2843
except errors.NoSuchExportFormat, e:
2820
2844
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
3116
3140
'(use --file "%(f)s" to take commit message from that file)'
3117
3141
% { 'f': message })
3118
3142
ui.ui_factory.show_warning(warning_msg)
3144
message = message.replace('\r\n', '\n')
3145
message = message.replace('\r', '\n')
3147
raise errors.BzrCommandError(
3148
"please specify either --message or --file")
3120
3150
def get_message(commit_obj):
3121
3151
"""Callback to get commit message"""
3122
my_message = message
3123
if my_message is not None and '\r' in my_message:
3124
my_message = my_message.replace('\r\n', '\n')
3125
my_message = my_message.replace('\r', '\n')
3126
if my_message is None and not file:
3127
t = make_commit_message_template_encoded(tree,
3153
my_message = codecs.open(
3154
file, 'rt', osutils.get_user_encoding()).read()
3155
elif message is not None:
3156
my_message = message
3158
# No message supplied: make one up.
3159
# text is the status of the tree
3160
text = make_commit_message_template_encoded(tree,
3128
3161
selected_list, diff=show_diff,
3129
3162
output_encoding=osutils.get_user_encoding())
3163
# start_message is the template generated from hooks
3164
# XXX: Warning - looks like hooks return unicode,
3165
# make_commit_message_template_encoded returns user encoding.
3166
# We probably want to be using edit_commit_message instead to
3130
3168
start_message = generate_commit_message_template(commit_obj)
3131
my_message = edit_commit_message_encoded(t,
3169
my_message = edit_commit_message_encoded(text,
3132
3170
start_message=start_message)
3133
3171
if my_message is None:
3134
3172
raise errors.BzrCommandError("please specify a commit"
3135
3173
" message with either --message or --file")
3136
elif my_message and file:
3137
raise errors.BzrCommandError(
3138
"please specify either --message or --file")
3140
my_message = codecs.open(file, 'rt',
3141
osutils.get_user_encoding()).read()
3142
3174
if my_message == "":
3143
3175
raise errors.BzrCommandError("empty commit message specified")
3144
3176
return my_message
3156
3188
timezone=offset,
3157
3189
exclude=safe_relpath_files(tree, exclude))
3158
3190
except PointlessCommit:
3159
# FIXME: This should really happen before the file is read in;
3160
# perhaps prepare the commit; get the message; then actually commit
3161
3191
raise errors.BzrCommandError("No changes to commit."
3162
3192
" Use --unchanged to commit anyhow.")
3163
3193
except ConflictsInTree:
3168
3198
raise errors.BzrCommandError("Commit refused because there are"
3169
3199
" unknown files in the working tree.")
3170
3200
except errors.BoundBranchOutOfDate, e:
3171
raise errors.BzrCommandError(str(e) + "\n"
3172
'To commit to master branch, run update and then commit.\n'
3173
'You can also pass --local to commit to continue working '
3201
e.extra_help = ("\n"
3202
'To commit to master branch, run update and then commit.\n'
3203
'You can also pass --local to commit to continue working '
3177
3208
class cmd_check(Command):
3645
3676
graph = branch1.repository.get_graph(branch2.repository)
3646
3677
base_rev_id = graph.find_unique_lca(last1, last2)
3648
print 'merge base is revision %s' % base_rev_id
3679
self.outf.write('merge base is revision %s\n' % base_rev_id)
3651
3682
class cmd_merge(Command):
4042
4073
def run(self, file_list=None, merge_type=None, show_base=False,
4043
4074
reprocess=False):
4075
from bzrlib.conflicts import restore
4044
4076
if merge_type is None:
4045
4077
merge_type = _mod_merge.Merge3Merger
4046
4078
tree, file_list = tree_files(file_list)
4318
4353
remote_branch = Branch.open(other_branch)
4319
4354
if remote_branch.base == local_branch.base:
4320
4355
remote_branch = local_branch
4357
remote_branch.lock_read()
4358
self.add_cleanup(remote_branch.unlock)
4322
local_branch.lock_read()
4323
self.add_cleanup(local_branch.unlock)
4324
4360
local_revid_range = _revision_range_to_revid_range(
4325
4361
_get_revision_range(my_revision, local_branch,
4328
remote_branch.lock_read()
4329
self.add_cleanup(remote_branch.unlock)
4330
4364
remote_revid_range = _revision_range_to_revid_range(
4331
4365
_get_revision_range(revision,
4332
4366
remote_branch, self.name()))
4444
4478
doc = '(no description)'
4445
4479
result.append((name_ver, doc, plugin.path()))
4446
4480
for name_ver, doc, path in sorted(result):
4481
self.outf.write("%s\n" % name_ver)
4482
self.outf.write(" %s\n" % doc)
4484
self.outf.write(" %s\n" % path)
4485
self.outf.write("\n")
4454
4488
class cmd_testament(Command):
4734
4768
rev_id = b.get_rev_id(revno)
4736
4770
if rev_id is None or _mod_revision.is_null(rev_id):
4737
ui.ui_factory.note('No revisions to uncommit.')
4771
self.outf.write('No revisions to uncommit.\n')
4740
log_collector = ui.ui_factory.make_output_stream()
4741
4774
lf = log_formatter('short',
4742
to_file=log_collector,
4743
4776
show_timezone='original')
4750
4783
end_revision=last_revno)
4753
ui.ui_factory.note('Dry-run, pretending to remove the above revisions.')
4786
self.outf.write('Dry-run, pretending to remove'
4787
' the above revisions.\n')
4755
ui.ui_factory.note('The above revision(s) will be removed.')
4789
self.outf.write('The above revision(s) will be removed.\n')
4758
if not ui.ui_factory.get_boolean('Are you sure [y/N]? '):
4759
ui.ui_factory.note('Canceled')
4792
if not ui.ui_factory.get_boolean('Are you sure'):
4793
self.outf.write('Canceled')
4762
4796
mutter('Uncommitting from {%s} to {%s}',
4763
4797
last_rev_id, rev_id)
4764
4798
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4765
4799
revno=revno, local=local)
4766
ui.ui_factory.note('You can restore the old tip by running:\n'
4767
' bzr pull . -r revid:%s' % last_rev_id)
4800
self.outf.write('You can restore the old tip by running:\n'
4801
' bzr pull . -r revid:%s\n' % last_rev_id)
4770
4804
class cmd_break_lock(Command):
5249
5283
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5250
5284
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5286
If no tag name is specified it will be determined through the
5287
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5288
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5253
5292
_see_also = ['commit', 'tags']
5254
takes_args = ['tag_name']
5293
takes_args = ['tag_name?']
5255
5294
takes_options = [
5256
5295
Option('delete',
5257
5296
help='Delete this tag rather than placing it.',
5288
5329
revision_id = revision[0].as_revision_id(branch)
5290
5331
revision_id = branch.last_revision()
5332
if tag_name is None:
5333
tag_name = branch.automatic_tag_name(revision_id)
5334
if tag_name is None:
5335
raise errors.BzrCommandError(
5336
"Please specify a tag name.")
5291
5337
if (not force) and branch.tags.has_tag(tag_name):
5292
5338
raise errors.TagAlreadyExists(tag_name)
5293
5339
branch.tags.set_tag(tag_name, revision_id)
5729
5775
self.outf.write(" <no hooks installed>\n")
5778
class cmd_remove_branch(Command):
5781
This will remove the branch from the specified location but
5782
will keep any working tree or repository in place.
5786
Remove the branch at repo/trunk::
5788
bzr remove-branch repo/trunk
5792
takes_args = ["location?"]
5794
aliases = ["rmbranch"]
5796
def run(self, location=None):
5797
if location is None:
5799
branch = Branch.open_containing(location)[0]
5800
branch.bzrdir.destroy_branch()
5732
5803
class cmd_shelve(Command):
5733
5804
"""Temporarily set aside some changes from the current tree.
5917
5988
self.outf.write('%s %s\n' % (path, location))
5920
# these get imported and then picked up by the scan for cmd_*
5921
# TODO: Some more consistent way to split command definitions across files;
5922
# we do need to load at least some information about them to know of
5923
# aliases. ideally we would avoid loading the implementation until the
5924
# details were needed.
5925
from bzrlib.cmd_version_info import cmd_version_info
5926
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5927
from bzrlib.bundle.commands import (
5930
from bzrlib.foreign import cmd_dpush
5931
from bzrlib.sign_my_commits import cmd_sign_my_commits
5991
def _register_lazy_builtins():
5992
# register lazy builtins from other modules; called at startup and should
5993
# be only called once.
5994
for (name, aliases, module_name) in [
5995
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
5996
('cmd_dpush', [], 'bzrlib.foreign'),
5997
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
5998
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
5999
('cmd_conflicts', [], 'bzrlib.conflicts'),
6000
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6002
builtin_command_registry.register_lazy(name, aliases, module_name)