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 (
330
334
class cmd_cat_revision(Command):
331
"""Write out metadata for a revision.
335
__doc__ = """Write out metadata for a revision.
333
337
The revision to print can either be specified by a specific
334
338
revision identifier, or you can use --revision.
388
392
class cmd_dump_btree(Command):
389
"""Dump the contents of a btree index file to stdout.
393
__doc__ = """Dump the contents of a btree index file to stdout.
391
395
PATH is a btree index file, it can be any URL. This includes things like
392
396
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
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,))
464
473
class cmd_remove_tree(Command):
465
"""Remove the working tree from a given branch/checkout.
474
__doc__ = """Remove the working tree from a given branch/checkout.
467
476
Since a lightweight checkout is little more than a working tree
468
477
this will refuse to run against one.
495
504
if (working.has_changes()):
496
505
raise errors.UncommittedChanges(working)
498
working_path = working.bzrdir.root_transport.base
499
branch_path = working.branch.bzrdir.root_transport.base
500
if working_path != branch_path:
507
if working.user_url != working.branch.user_url:
501
508
raise errors.BzrCommandError("You cannot remove the working tree"
502
509
" from a lightweight checkout")
700
707
def run(self, dir_list):
701
708
for d in dir_list:
703
709
wt, dd = WorkingTree.open_containing(d)
705
self.outf.write('added %s\n' % d)
710
base = os.path.dirname(dd)
711
id = wt.path2id(base)
715
self.outf.write('added %s\n' % d)
717
raise errors.NotVersionedError(path=base)
708
720
class cmd_relpath(Command):
709
"""Show path of a file relative to root"""
721
__doc__ = """Show path of a file relative to root"""
711
723
takes_args = ['filename']
975
987
tree_to = WorkingTree.open_containing(directory)[0]
976
988
branch_to = tree_to.branch
990
self.add_cleanup(tree_to.unlock)
977
991
except errors.NoWorkingTree:
979
993
branch_to = Branch.open_containing(directory)[0]
994
branch_to.lock_write()
995
self.add_cleanup(branch_to.unlock)
981
997
if local and not branch_to.get_bound_location():
982
998
raise errors.LocalRequiresBoundBranch()
1014
1030
branch_from = Branch.open(location,
1015
1031
possible_transports=possible_transports)
1032
branch_from.lock_read()
1033
self.add_cleanup(branch_from.unlock)
1017
1035
if branch_to.get_parent() is None or remember:
1018
1036
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
1038
if revision is not None:
1024
1039
revision_id = revision.as_revision_id(branch_from)
1026
branch_to.lock_write()
1027
self.add_cleanup(branch_to.unlock)
1028
1041
if tree_to is not None:
1029
1042
view_info = _get_view_info_for_change_reporter(tree_to)
1030
1043
change_reporter = delta._ChangeReporter(
1112
1125
# Get the source branch
1113
1126
(tree, br_from,
1114
1127
_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
1128
# Get the tip's revision_id
1119
1129
revision = _get_one_revision('push', revision)
1120
1130
if revision is not None:
1121
1131
revision_id = revision.in_history(br_from).rev_id
1123
1133
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.')
1134
if tree is not None and revision_id is None:
1135
tree.check_changed_or_out_of_date(
1136
strict, 'push_strict',
1137
more_error='Use --no-strict to force the push.',
1138
more_warning='Uncommitted changes will not be pushed.')
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)
1171
1175
class cmd_branch(Command):
1172
"""Create a new branch that is a copy of an existing branch.
1176
__doc__ = """Create a new branch that is a copy of an existing branch.
1174
1178
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1175
1179
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1284
1288
class cmd_checkout(Command):
1285
"""Create a new checkout of an existing branch.
1289
__doc__ = """Create a new checkout of an existing branch.
1287
1291
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1288
1292
the branch found in '.'. This is useful if you have removed the working tree
1385
1389
class cmd_update(Command):
1386
"""Update a tree to have the latest code committed to its branch.
1390
__doc__ = """Update a tree to have the latest code committed to its branch.
1388
1392
This will perform a merge into the working tree, and may generate
1389
1393
conflicts. If you have any local changes, you will still
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))
1460
if tree.get_parent_ids()[1:] != existing_pending_merges:
1463
note('Updated to revision %s of branch %s' %
1464
('.'.join(map(str, revno)), branch_location))
1465
parent_ids = tree.get_parent_ids()
1466
if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1461
1467
note('Your local commits will now show as pending merges with '
1462
1468
"'bzr status', and can be committed with 'bzr commit'.")
1463
1469
if conflicts != 0:
1469
1475
class cmd_info(Command):
1470
"""Show information about a working tree, branch or repository.
1476
__doc__ = """Show information about a working tree, branch or repository.
1472
1478
This command will show all known locations and formats associated to the
1473
1479
tree, branch or repository.
1567
1573
class cmd_file_id(Command):
1568
"""Print file_id of a particular file or directory.
1574
__doc__ = """Print file_id of a particular file or directory.
1570
1576
The file_id is assigned when the file is first added and remains the
1571
1577
same through all revisions where the file exists, even when it is
1589
1595
class cmd_file_path(Command):
1590
"""Print path of file_ids to a file or directory.
1596
__doc__ = """Print path of file_ids to a file or directory.
1592
1598
This prints one line for each directory down to the target,
1593
1599
starting at the branch root.
1655
1661
class cmd_ancestry(Command):
1656
"""List all revisions merged into this branch."""
1662
__doc__ = """List all revisions merged into this branch."""
1658
1664
_see_also = ['log', 'revision-history']
1659
1665
takes_args = ['location?']
1789
1795
class cmd_init_repository(Command):
1790
"""Create a shared repository for branches to share storage space.
1796
__doc__ = """Create a shared repository for branches to share storage space.
1792
1798
New branches created under the repository directory will store their
1793
1799
revisions in the repository, not in the branch directory. For branches
1849
1855
class cmd_diff(Command):
1850
"""Show differences in the working tree, between revisions or branches.
1856
__doc__ = """Show differences in the working tree, between revisions or branches.
1852
1858
If no arguments are given, all changes for the current tree are listed.
1853
1859
If files are given, only the changes in those files are listed.
1939
1945
help='Use this command to compare files.',
1948
RegistryOption('format',
1949
help='Diff format to use.',
1950
lazy_registry=('bzrlib.diff', 'format_registry'),
1951
value_switches=False, title='Diff format'),
1943
1953
aliases = ['di', 'dif']
1944
1954
encoding_type = 'exact'
1946
1956
@display_command
1947
1957
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
1958
prefix=None, old=None, new=None, using=None, format=None):
1959
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
1951
1962
if (prefix is None) or (prefix == '0'):
1952
1963
# diff -p0 format
1966
1977
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1967
1978
' one or two revision specifiers')
1980
if using is not None and format is not None:
1981
raise errors.BzrCommandError('--using and --format are mutually '
1969
1984
(old_tree, new_tree,
1970
1985
old_branch, new_branch,
1971
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1972
file_list, revision, old, new, apply_view=True)
1986
specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
1987
file_list, revision, old, new, self.add_cleanup, apply_view=True)
1973
1988
return show_diff_trees(old_tree, new_tree, sys.stdout,
1974
1989
specific_files=specific_files,
1975
1990
external_diff_options=diff_options,
1976
1991
old_label=old_label, new_label=new_label,
1977
extra_trees=extra_trees, using=using)
1992
extra_trees=extra_trees, using=using,
1980
1996
class cmd_deleted(Command):
1981
"""List files deleted in the working tree.
1997
__doc__ = """List files deleted in the working tree.
1983
1999
# TODO: Show files deleted since a previous revision, or
1984
2000
# between two revisions.
2283
2299
help='Show changes made in each revision as a patch.'),
2284
2300
Option('include-merges',
2285
2301
help='Show merged revisions like --levels 0 does.'),
2302
Option('exclude-common-ancestry',
2303
help='Display only the revisions that are not part'
2304
' of both ancestries (require -rX..Y)'
2287
2307
encoding_type = 'replace'
2300
2320
show_diff=False,
2301
include_merges=False):
2321
include_merges=False,
2322
exclude_common_ancestry=False,
2302
2324
from bzrlib.log import (
2304
2326
make_log_request_dict,
2305
2327
_get_info_for_log_files,
2307
2329
direction = (forward and 'forward') or 'reverse'
2330
if (exclude_common_ancestry
2331
and (revision is None or len(revision) != 2)):
2332
raise errors.BzrCommandError(
2333
'--exclude-common-ancestry requires -r with two revisions')
2308
2334
if include_merges:
2309
2335
if levels is None:
2403
2429
direction=direction, specific_fileids=file_ids,
2404
2430
start_revision=rev1, end_revision=rev2, limit=limit,
2405
2431
message_search=message, delta_type=delta_type,
2406
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2432
diff_type=diff_type, _match_using_deltas=match_using_deltas,
2433
exclude_common_ancestry=exclude_common_ancestry,
2407
2435
Logger(b, rqst).show(lf)
2428
2456
raise errors.BzrCommandError(
2429
2457
"bzr %s doesn't accept two revisions in different"
2430
2458
" branches." % command_name)
2431
rev1 = start_spec.in_history(branch)
2459
if start_spec.spec is None:
2460
# Avoid loading all the history.
2461
rev1 = RevisionInfo(branch, None, None)
2463
rev1 = start_spec.in_history(branch)
2432
2464
# Avoid loading all of history when we know a missing
2433
2465
# end of range means the last revision ...
2434
2466
if end_spec.spec is None:
2629
2661
using this command or directly by using an editor, be sure to commit
2664
Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
2665
the global ignore file can be found in the application data directory as
2666
C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
2667
Global ignores are not touched by this command. The global ignore file
2668
can be edited directly using an editor.
2632
2670
Patterns prefixed with '!' are exceptions to ignore patterns and take
2633
2671
precedence over regular ignores. Such exceptions are used to specify
2634
2672
files that should be versioned which would otherwise be ignored.
2675
2713
_see_also = ['status', 'ignored', 'patterns']
2676
2714
takes_args = ['name_pattern*']
2677
2715
takes_options = [
2678
Option('old-default-rules',
2679
help='Write out the ignore rules bzr < 0.9 always used.')
2716
Option('default-rules',
2717
help='Display the default ignore rules that bzr uses.')
2682
def run(self, name_pattern_list=None, old_default_rules=None):
2720
def run(self, name_pattern_list=None, default_rules=None):
2683
2721
from bzrlib import ignores
2684
if old_default_rules is not None:
2685
# dump the rules and exit
2686
for pattern in ignores.OLD_DEFAULTS:
2722
if default_rules is not None:
2723
# dump the default rules and exit
2724
for pattern in ignores.USER_DEFAULTS:
2725
self.outf.write("%s\n" % pattern)
2689
2727
if not name_pattern_list:
2690
2728
raise errors.BzrCommandError("ignore requires at least one "
2691
"NAME_PATTERN or --old-default-rules")
2729
"NAME_PATTERN or --default-rules.")
2692
2730
name_pattern_list = [globbing.normalize_pattern(p)
2693
2731
for p in name_pattern_list]
2694
2732
for name_pattern in name_pattern_list:
2706
2744
if id is not None:
2707
2745
filename = entry[0]
2708
2746
if ignored.match(filename):
2709
matches.append(filename.encode('utf-8'))
2747
matches.append(filename)
2711
2749
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),)
2750
self.outf.write("Warning: the following files are version controlled and"
2751
" match your ignore pattern:\n%s"
2752
"\nThese files will continue to be version controlled"
2753
" unless you 'bzr remove' them.\n" % ("\n".join(matches),))
2718
2756
class cmd_ignored(Command):
2719
"""List ignored files and the patterns that matched them.
2757
__doc__ = """List ignored files and the patterns that matched them.
2721
2759
List all the ignored files and the ignore pattern that caused the file to
2757
2795
revno = int(revno)
2758
2796
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)
2797
raise errors.BzrCommandError("not a valid revision-number: %r"
2799
revid = WorkingTree.open_containing(u'.')[0].branch.get_rev_id(revno)
2800
self.outf.write("%s\n" % revid)
2764
2803
class cmd_export(Command):
2765
"""Export current or past revision to a destination directory or archive.
2804
__doc__ = """Export current or past revision to a destination directory or archive.
2767
2806
If no revision is specified this exports the last committed revision.
2802
2841
help="Name of the root directory inside the exported file."),
2842
Option('per-file-timestamps',
2843
help='Set modification time of files to that of the last '
2844
'revision in which it was changed.'),
2804
2846
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2805
root=None, filters=False):
2847
root=None, filters=False, per_file_timestamps=False):
2806
2848
from bzrlib.export import export
2808
2850
if branch_or_subdir is None:
2816
2858
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2818
export(rev_tree, dest, format, root, subdir, filtered=filters)
2860
export(rev_tree, dest, format, root, subdir, filtered=filters,
2861
per_file_timestamps=per_file_timestamps)
2819
2862
except errors.NoSuchExportFormat, e:
2820
2863
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2823
2866
class cmd_cat(Command):
2824
"""Write the contents of a file as of a given revision to standard output.
2867
__doc__ = """Write the contents of a file as of a given revision to standard output.
2826
2869
If no revision is nominated, the last revision is used.
2909
2952
class cmd_local_time_offset(Command):
2910
"""Show the offset in seconds from GMT to local time."""
2953
__doc__ = """Show the offset in seconds from GMT to local time."""
2912
2955
@display_command
2914
print osutils.local_time_offset()
2957
self.outf.write("%s\n" % osutils.local_time_offset())
2918
2961
class cmd_commit(Command):
2919
"""Commit changes into a new revision.
2962
__doc__ = """Commit changes into a new revision.
2921
2964
An explanatory message needs to be given for each commit. This is
2922
2965
often done by using the --message option (getting the message from the
3030
3073
"the master branch until a normal commit "
3031
3074
"is performed."
3076
Option('show-diff', short_name='p',
3034
3077
help='When no message is supplied, show the diff along'
3035
3078
' with the status summary in the message editor.'),
3116
3159
'(use --file "%(f)s" to take commit message from that file)'
3117
3160
% { 'f': message })
3118
3161
ui.ui_factory.show_warning(warning_msg)
3163
message = message.replace('\r\n', '\n')
3164
message = message.replace('\r', '\n')
3166
raise errors.BzrCommandError(
3167
"please specify either --message or --file")
3120
3169
def get_message(commit_obj):
3121
3170
"""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,
3172
my_message = codecs.open(
3173
file, 'rt', osutils.get_user_encoding()).read()
3174
elif message is not None:
3175
my_message = message
3177
# No message supplied: make one up.
3178
# text is the status of the tree
3179
text = make_commit_message_template_encoded(tree,
3128
3180
selected_list, diff=show_diff,
3129
3181
output_encoding=osutils.get_user_encoding())
3182
# start_message is the template generated from hooks
3183
# XXX: Warning - looks like hooks return unicode,
3184
# make_commit_message_template_encoded returns user encoding.
3185
# We probably want to be using edit_commit_message instead to
3130
3187
start_message = generate_commit_message_template(commit_obj)
3131
my_message = edit_commit_message_encoded(t,
3188
my_message = edit_commit_message_encoded(text,
3132
3189
start_message=start_message)
3133
3190
if my_message is None:
3134
3191
raise errors.BzrCommandError("please specify a commit"
3135
3192
" 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
3193
if my_message == "":
3143
3194
raise errors.BzrCommandError("empty commit message specified")
3144
3195
return my_message
3156
3207
timezone=offset,
3157
3208
exclude=safe_relpath_files(tree, exclude))
3158
3209
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
3210
raise errors.BzrCommandError("No changes to commit."
3162
3211
" Use --unchanged to commit anyhow.")
3163
3212
except ConflictsInTree:
3168
3217
raise errors.BzrCommandError("Commit refused because there are"
3169
3218
" unknown files in the working tree.")
3170
3219
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 '
3220
e.extra_help = ("\n"
3221
'To commit to master branch, run update and then commit.\n'
3222
'You can also pass --local to commit to continue working '
3177
3227
class cmd_check(Command):
3178
"""Validate working tree structure, branch consistency and repository history.
3228
__doc__ = """Validate working tree structure, branch consistency and repository history.
3180
3230
This command checks various invariants about branch and repository storage
3181
3231
to detect data corruption or bzr bugs.
3340
3390
@display_command
3341
3391
def printme(self, branch):
3392
self.outf.write('%s\n' % branch.nick)
3345
3395
class cmd_alias(Command):
3346
"""Set/unset and display aliases.
3396
__doc__ = """Set/unset and display aliases.
3349
3399
Show the current aliases::
3415
3465
class cmd_selftest(Command):
3416
"""Run internal test suite.
3466
__doc__ = """Run internal test suite.
3418
3468
If arguments are given, they are regular expressions that say which tests
3419
3469
should run. Tests matching any expression are run, and other tests are
3560
3610
raise errors.BzrCommandError("subunit not available. subunit "
3561
3611
"needs to be installed to use --subunit.")
3562
3612
self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
3613
# On Windows, disable automatic conversion of '\n' to '\r\n' in
3614
# stdout, which would corrupt the subunit stream.
3615
if sys.platform == "win32" and sys.stdout.fileno() >= 0:
3617
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
3564
3619
self.additional_selftest_args.setdefault(
3565
3620
'suite_decorators', []).append(parallel)
3615
3670
class cmd_rocks(Command):
3616
"""Statement of optimism."""
3671
__doc__ = """Statement of optimism."""
3620
3675
@display_command
3622
print "It sure does!"
3677
self.outf.write("It sure does!\n")
3625
3680
class cmd_find_merge_base(Command):
3626
"""Find and print a base revision for merging two branches."""
3681
__doc__ = """Find and print a base revision for merging two branches."""
3627
3682
# TODO: Options to specify revisions on either side, as if
3628
3683
# merging only part of the history.
3629
3684
takes_args = ['branch', 'other']
3645
3700
graph = branch1.repository.get_graph(branch2.repository)
3646
3701
base_rev_id = graph.find_unique_lca(last1, last2)
3648
print 'merge base is revision %s' % base_rev_id
3703
self.outf.write('merge base is revision %s\n' % base_rev_id)
3651
3706
class cmd_merge(Command):
3652
"""Perform a three-way merge.
3707
__doc__ = """Perform a three-way merge.
3654
3709
The source of the merge can be specified either in the form of a branch,
3655
3710
or in the form of a path to a file containing a merge directive generated
4042
4097
def run(self, file_list=None, merge_type=None, show_base=False,
4043
4098
reprocess=False):
4099
from bzrlib.conflicts import restore
4044
4100
if merge_type is None:
4045
4101
merge_type = _mod_merge.Merge3Merger
4046
4102
tree, file_list = tree_files(file_list)
4106
4162
class cmd_revert(Command):
4107
"""Revert files to a previous revision.
4163
__doc__ = """Revert files to a previous revision.
4109
4165
Giving a list of files will revert only those files. Otherwise, all files
4110
4166
will be reverted. If the revision is not specified with '--revision', the
4161
4217
def run(self, revision=None, no_backup=False, file_list=None,
4162
4218
forget_merges=None):
4163
4219
tree, file_list = tree_files(file_list)
4220
tree.lock_tree_write()
4165
4221
self.add_cleanup(tree.unlock)
4166
4222
if forget_merges:
4167
4223
tree.set_parent_ids(tree.get_parent_ids()[:1])
4318
4377
remote_branch = Branch.open(other_branch)
4319
4378
if remote_branch.base == local_branch.base:
4320
4379
remote_branch = local_branch
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4322
local_branch.lock_read()
4323
self.add_cleanup(local_branch.unlock)
4324
4384
local_revid_range = _revision_range_to_revid_range(
4325
4385
_get_revision_range(my_revision, local_branch,
4328
remote_branch.lock_read()
4329
self.add_cleanup(remote_branch.unlock)
4330
4388
remote_revid_range = _revision_range_to_revid_range(
4331
4389
_get_revision_range(revision,
4332
4390
remote_branch, self.name()))
4393
4451
class cmd_pack(Command):
4394
"""Compress the data within a repository."""
4452
__doc__ = """Compress the data within a repository.
4454
This operation compresses the data within a bazaar repository. As
4455
bazaar supports automatic packing of repository, this operation is
4456
normally not required to be done manually.
4458
During the pack operation, bazaar takes a backup of existing repository
4459
data, i.e. pack files. This backup is eventually removed by bazaar
4460
automatically when it is safe to do so. To save disk space by removing
4461
the backed up pack files, the --clean-obsolete-packs option may be
4464
Warning: If you use --clean-obsolete-packs and your machine crashes
4465
during or immediately after repacking, you may be left with a state
4466
where the deletion has been written to disk but the new packs have not
4467
been. In this case the repository may be unusable.
4396
4470
_see_also = ['repositories']
4397
4471
takes_args = ['branch_or_repo?']
4473
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4399
def run(self, branch_or_repo='.'):
4476
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4400
4477
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4402
4479
branch = dir.open_branch()
4403
4480
repository = branch.repository
4404
4481
except errors.NotBranchError:
4405
4482
repository = dir.open_repository()
4483
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4409
4486
class cmd_plugins(Command):
4410
"""List the installed plugins.
4487
__doc__ = """List the installed plugins.
4412
4489
This command displays the list of installed plugins including
4413
4490
version of plugin and a short description of each.
4444
4521
doc = '(no description)'
4445
4522
result.append((name_ver, doc, plugin.path()))
4446
4523
for name_ver, doc, path in sorted(result):
4524
self.outf.write("%s\n" % name_ver)
4525
self.outf.write(" %s\n" % doc)
4527
self.outf.write(" %s\n" % path)
4528
self.outf.write("\n")
4454
4531
class cmd_testament(Command):
4455
"""Show testament (signing-form) of a revision."""
4532
__doc__ = """Show testament (signing-form) of a revision."""
4456
4533
takes_options = [
4458
4535
Option('long', help='Produce long-format testament.'),
4486
4563
class cmd_annotate(Command):
4487
"""Show the origin of each line in a file.
4564
__doc__ = """Show the origin of each line in a file.
4489
4566
This prints out the given file with an annotation on the left side
4490
4567
indicating which revision, author and date introduced the change.
4605
4682
class cmd_bind(Command):
4606
"""Convert the current branch into a checkout of the supplied branch.
4683
__doc__ = """Convert the current branch into a checkout of the supplied branch.
4684
If no branch is supplied, rebind to the last bound location.
4608
4686
Once converted into a checkout, commits must succeed on the master branch
4609
4687
before they will be applied to the local branch.
4645
4723
class cmd_unbind(Command):
4646
"""Convert the current checkout into a regular branch.
4724
__doc__ = """Convert the current checkout into a regular branch.
4648
4726
After unbinding, the local branch is considered independent and subsequent
4649
4727
commits will be local only.
4662
4740
class cmd_uncommit(Command):
4663
"""Remove the last committed revision.
4741
__doc__ = """Remove the last committed revision.
4665
4743
--verbose will print out what is being removed.
4666
4744
--dry-run will go through all the motions, but not actually
4734
4812
rev_id = b.get_rev_id(revno)
4736
4814
if rev_id is None or _mod_revision.is_null(rev_id):
4737
ui.ui_factory.note('No revisions to uncommit.')
4815
self.outf.write('No revisions to uncommit.\n')
4740
log_collector = ui.ui_factory.make_output_stream()
4741
4818
lf = log_formatter('short',
4742
to_file=log_collector,
4743
4820
show_timezone='original')
4750
4827
end_revision=last_revno)
4753
ui.ui_factory.note('Dry-run, pretending to remove the above revisions.')
4830
self.outf.write('Dry-run, pretending to remove'
4831
' the above revisions.\n')
4755
ui.ui_factory.note('The above revision(s) will be removed.')
4833
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')
4836
if not ui.ui_factory.get_boolean('Are you sure'):
4837
self.outf.write('Canceled')
4762
4840
mutter('Uncommitting from {%s} to {%s}',
4763
4841
last_rev_id, rev_id)
4764
4842
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4765
4843
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)
4844
self.outf.write('You can restore the old tip by running:\n'
4845
' bzr pull . -r revid:%s\n' % last_rev_id)
4770
4848
class cmd_break_lock(Command):
4771
"""Break a dead lock on a repository, branch or working directory.
4849
__doc__ = """Break a dead lock on a repository, branch or working directory.
4773
4851
CAUTION: Locks should only be broken when you are sure that the process
4774
4852
holding the lock has been stopped.
4921
4999
class cmd_split(Command):
4922
"""Split a subdirectory of a tree into a separate tree.
5000
__doc__ = """Split a subdirectory of a tree into a separate tree.
4924
5002
This command will produce a target tree in a format that supports
4925
5003
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4947
5025
class cmd_merge_directive(Command):
4948
"""Generate a merge directive for auto-merge tools.
5026
__doc__ = """Generate a merge directive for auto-merge tools.
4950
5028
A directive requests a merge to be performed, and also provides all the
4951
5029
information necessary to do so. This means it must either include a
5236
5314
class cmd_tag(Command):
5237
"""Create, remove or modify a tag naming a revision.
5315
__doc__ = """Create, remove or modify a tag naming a revision.
5239
5317
Tags give human-meaningful names to revisions. Commands that take a -r
5240
5318
(--revision) option can be given -rtag:X, where X is any previously
5249
5327
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5250
5328
tag new-name -r tag:old-name`` and then ``bzr tag --delete oldname``.
5330
If no tag name is specified it will be determined through the
5331
'automatic_tag_name' hook. This can e.g. be used to automatically tag
5332
upstream releases by reading configure.ac. See ``bzr help hooks`` for
5253
5336
_see_also = ['commit', 'tags']
5254
takes_args = ['tag_name']
5337
takes_args = ['tag_name?']
5255
5338
takes_options = [
5256
5339
Option('delete',
5257
5340
help='Delete this tag rather than placing it.',
5288
5373
revision_id = revision[0].as_revision_id(branch)
5290
5375
revision_id = branch.last_revision()
5376
if tag_name is None:
5377
tag_name = branch.automatic_tag_name(revision_id)
5378
if tag_name is None:
5379
raise errors.BzrCommandError(
5380
"Please specify a tag name.")
5291
5381
if (not force) and branch.tags.has_tag(tag_name):
5292
5382
raise errors.TagAlreadyExists(tag_name)
5293
5383
branch.tags.set_tag(tag_name, revision_id)
5462
5552
class cmd_switch(Command):
5463
"""Set the branch of a checkout and update.
5553
__doc__ = """Set the branch of a checkout and update.
5465
5555
For lightweight checkouts, this changes the branch being referenced.
5466
5556
For heavyweight checkouts, this checks that there are no local commits
5729
5819
self.outf.write(" <no hooks installed>\n")
5822
class cmd_remove_branch(Command):
5823
__doc__ = """Remove a branch.
5825
This will remove the branch from the specified location but
5826
will keep any working tree or repository in place.
5830
Remove the branch at repo/trunk::
5832
bzr remove-branch repo/trunk
5836
takes_args = ["location?"]
5838
aliases = ["rmbranch"]
5840
def run(self, location=None):
5841
if location is None:
5843
branch = Branch.open_containing(location)[0]
5844
branch.bzrdir.destroy_branch()
5732
5847
class cmd_shelve(Command):
5733
"""Temporarily set aside some changes from the current tree.
5848
__doc__ = """Temporarily set aside some changes from the current tree.
5735
5850
Shelve allows you to temporarily put changes you've made "on the shelf",
5736
5851
ie. out of the way, until a later time when you can bring them back from
5807
5922
class cmd_unshelve(Command):
5808
"""Restore shelved changes.
5923
__doc__ = """Restore shelved changes.
5810
5925
By default, the most recently shelved changes are restored. However if you
5811
5926
specify a shelf by id those changes will be restored instead. This works
5839
5954
class cmd_clean_tree(Command):
5840
"""Remove unwanted files from working tree.
5955
__doc__ = """Remove unwanted files from working tree.
5842
5957
By default, only unknown files, not ignored files, are deleted. Versioned
5843
5958
files are never deleted.
5873
5988
class cmd_reference(Command):
5874
"""list, view and set branch locations for nested trees.
5989
__doc__ = """list, view and set branch locations for nested trees.
5876
5991
If no arguments are provided, lists the branch locations for nested trees.
5877
5992
If one argument is provided, display the branch location for that tree.
5917
6032
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
6035
def _register_lazy_builtins():
6036
# register lazy builtins from other modules; called at startup and should
6037
# be only called once.
6038
for (name, aliases, module_name) in [
6039
('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6040
('cmd_dpush', [], 'bzrlib.foreign'),
6041
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6042
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6043
('cmd_conflicts', [], 'bzrlib.conflicts'),
6044
('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6046
builtin_command_registry.register_lazy(name, aliases, module_name)