55
55
from bzrlib.branch import Branch
56
56
from bzrlib.conflicts import ConflictList
57
from bzrlib.transport import memory
57
58
from bzrlib.revisionspec import RevisionSpec, RevisionInfo
58
59
from bzrlib.smtp_connection import SMTPConnection
59
60
from bzrlib.workingtree import WorkingTree
62
from bzrlib.commands import Command, display_command
63
from bzrlib.commands import (
65
builtin_command_registry,
63
68
from bzrlib.option import (
329
334
class cmd_cat_revision(Command):
330
"""Write out metadata for a revision.
335
__doc__ = """Write out metadata for a revision.
332
337
The revision to print can either be specified by a specific
333
338
revision identifier, or you can use --revision.
339
344
# cat-revision is more for frontends so should be exact
340
345
encoding = 'strict'
347
def print_revision(self, revisions, revid):
348
stream = revisions.get_record_stream([(revid,)], 'unordered', True)
349
record = stream.next()
350
if record.storage_kind == 'absent':
351
raise errors.NoSuchRevision(revisions, revid)
352
revtext = record.get_bytes_as('fulltext')
353
self.outf.write(revtext.decode('utf-8'))
343
356
def run(self, revision_id=None, revision=None):
344
357
if revision_id is not None and revision is not None:
349
362
' --revision or a revision_id')
350
363
b = WorkingTree.open_containing(u'.')[0].branch
352
# TODO: jam 20060112 should cat-revision always output utf-8?
353
if revision_id is not None:
354
revision_id = osutils.safe_revision_id(revision_id, warn=False)
356
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
357
except errors.NoSuchRevision:
358
msg = "The repository %s contains no revision %s." % (b.repository.base,
360
raise errors.BzrCommandError(msg)
361
elif revision is not None:
364
raise errors.BzrCommandError('You cannot specify a NULL'
366
rev_id = rev.as_revision_id(b)
367
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
365
revisions = b.repository.revisions
366
if revisions is None:
367
raise errors.BzrCommandError('Repository %r does not support '
368
'access to raw revision texts')
370
b.repository.lock_read()
372
# TODO: jam 20060112 should cat-revision always output utf-8?
373
if revision_id is not None:
374
revision_id = osutils.safe_revision_id(revision_id, warn=False)
376
self.print_revision(revisions, revision_id)
377
except errors.NoSuchRevision:
378
msg = "The repository %s contains no revision %s." % (
379
b.repository.base, revision_id)
380
raise errors.BzrCommandError(msg)
381
elif revision is not None:
384
raise errors.BzrCommandError(
385
'You cannot specify a NULL revision.')
386
rev_id = rev.as_revision_id(b)
387
self.print_revision(revisions, rev_id)
389
b.repository.unlock()
370
392
class cmd_dump_btree(Command):
371
"""Dump the contents of a btree index file to stdout.
393
__doc__ = """Dump the contents of a btree index file to stdout.
373
395
PATH is a btree index file, it can be any URL. This includes things like
374
396
.bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
438
460
for node in bt.iter_all_entries():
439
461
# Node is made up of:
440
462
# (index, key, value, [references])
441
refs_as_tuples = static_tuple.as_tuples(node[3])
466
refs_as_tuples = None
468
refs_as_tuples = static_tuple.as_tuples(refs)
442
469
as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
443
470
self.outf.write('%s\n' % (as_tuple,))
446
473
class cmd_remove_tree(Command):
447
"""Remove the working tree from a given branch/checkout.
474
__doc__ = """Remove the working tree from a given branch/checkout.
449
476
Since a lightweight checkout is little more than a working tree
450
477
this will refuse to run against one.
452
479
To re-create the working tree, use "bzr checkout".
454
481
_see_also = ['checkout', 'working-trees']
455
takes_args = ['location?']
482
takes_args = ['location*']
456
483
takes_options = [
458
485
help='Remove the working tree even if it has '
459
486
'uncommitted changes.'),
462
def run(self, location='.', force=False):
463
d = bzrdir.BzrDir.open(location)
466
working = d.open_workingtree()
467
except errors.NoWorkingTree:
468
raise errors.BzrCommandError("No working tree to remove")
469
except errors.NotLocalUrl:
470
raise errors.BzrCommandError("You cannot remove the working tree"
473
if (working.has_changes()):
474
raise errors.UncommittedChanges(working)
476
working_path = working.bzrdir.root_transport.base
477
branch_path = working.branch.bzrdir.root_transport.base
478
if working_path != branch_path:
479
raise errors.BzrCommandError("You cannot remove the working tree"
480
" from a lightweight checkout")
482
d.destroy_workingtree()
489
def run(self, location_list, force=False):
490
if not location_list:
493
for location in location_list:
494
d = bzrdir.BzrDir.open(location)
497
working = d.open_workingtree()
498
except errors.NoWorkingTree:
499
raise errors.BzrCommandError("No working tree to remove")
500
except errors.NotLocalUrl:
501
raise errors.BzrCommandError("You cannot remove the working tree"
504
if (working.has_changes()):
505
raise errors.UncommittedChanges(working)
507
if working.user_url != working.branch.user_url:
508
raise errors.BzrCommandError("You cannot remove the working tree"
509
" from a lightweight checkout")
511
d.destroy_workingtree()
485
514
class cmd_revno(Command):
486
"""Show current revision number.
515
__doc__ = """Show current revision number.
488
517
This is equal to the number of revisions on this branch.
678
707
def run(self, dir_list):
679
708
for d in dir_list:
681
709
wt, dd = WorkingTree.open_containing(d)
683
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)
686
720
class cmd_relpath(Command):
687
"""Show path of a file relative to root"""
721
__doc__ = """Show path of a file relative to root"""
689
723
takes_args = ['filename']
953
987
tree_to = WorkingTree.open_containing(directory)[0]
954
988
branch_to = tree_to.branch
990
self.add_cleanup(tree_to.unlock)
955
991
except errors.NoWorkingTree:
957
993
branch_to = Branch.open_containing(directory)[0]
994
branch_to.lock_write()
995
self.add_cleanup(branch_to.unlock)
959
997
if local and not branch_to.get_bound_location():
960
998
raise errors.LocalRequiresBoundBranch()
992
1030
branch_from = Branch.open(location,
993
1031
possible_transports=possible_transports)
1032
branch_from.lock_read()
1033
self.add_cleanup(branch_from.unlock)
995
1035
if branch_to.get_parent() is None or remember:
996
1036
branch_to.set_parent(branch_from.base)
998
if branch_from is not branch_to:
999
branch_from.lock_read()
1000
self.add_cleanup(branch_from.unlock)
1001
1038
if revision is not None:
1002
1039
revision_id = revision.as_revision_id(branch_from)
1004
branch_to.lock_write()
1005
self.add_cleanup(branch_to.unlock)
1006
1041
if tree_to is not None:
1007
1042
view_info = _get_view_info_for_change_reporter(tree_to)
1008
1043
change_reporter = delta._ChangeReporter(
1090
1125
# Get the source branch
1091
1126
(tree, br_from,
1092
1127
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1096
1128
# Get the tip's revision_id
1097
1129
revision = _get_one_revision('push', revision)
1098
1130
if revision is not None:
1099
1131
revision_id = revision.in_history(br_from).rev_id
1101
1133
revision_id = None
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
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.')
1113
1139
# Get the stacked_on branch, if any
1114
1140
if stacked_on is not None:
1115
1141
stacked_on = urlutils.normalize_url(stacked_on)
1149
1175
class cmd_branch(Command):
1150
"""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.
1152
1178
If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
1153
1179
be used. In other words, "branch ../foo/bar" will attempt to create ./bar.
1262
1288
class cmd_checkout(Command):
1263
"""Create a new checkout of an existing branch.
1289
__doc__ = """Create a new checkout of an existing branch.
1265
1291
If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1266
1292
the branch found in '.'. This is useful if you have removed the working tree
1363
1389
class cmd_update(Command):
1364
"""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.
1366
1392
This will perform a merge into the working tree, and may generate
1367
1393
conflicts. If you have any local changes, you will still
1396
1422
branch_location = tree.branch.base
1397
1423
self.add_cleanup(tree.unlock)
1398
1424
# get rid of the final '/' and be ready for display
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1425
branch_location = urlutils.unescape_for_display(
1426
branch_location.rstrip('/'),
1401
1428
existing_pending_merges = tree.get_parent_ids()[1:]
1402
1429
if master is None:
1412
1439
revision_id = branch.last_revision()
1413
1440
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1414
revno = branch.revision_id_to_revno(revision_id)
1415
note("Tree is up to date at revision %d of branch %s" %
1416
(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))
1418
1445
view_info = _get_view_info_for_change_reporter(tree)
1419
1446
change_reporter = delta._ChangeReporter(
1431
1458
"bzr update --revision only works"
1432
1459
" for a revision in the branch history"
1433
1460
% (e.revision))
1434
revno = tree.branch.revision_id_to_revno(
1461
revno = tree.branch.revision_id_to_dotted_revno(
1435
1462
_mod_revision.ensure_null(tree.last_revision()))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
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:
1439
1467
note('Your local commits will now show as pending merges with '
1440
1468
"'bzr status', and can be committed with 'bzr commit'.")
1441
1469
if conflicts != 0:
1447
1475
class cmd_info(Command):
1448
"""Show information about a working tree, branch or repository.
1476
__doc__ = """Show information about a working tree, branch or repository.
1450
1478
This command will show all known locations and formats associated to the
1451
1479
tree, branch or repository.
1545
1573
class cmd_file_id(Command):
1546
"""Print file_id of a particular file or directory.
1574
__doc__ = """Print file_id of a particular file or directory.
1548
1576
The file_id is assigned when the file is first added and remains the
1549
1577
same through all revisions where the file exists, even when it is
1567
1595
class cmd_file_path(Command):
1568
"""Print path of file_ids to a file or directory.
1596
__doc__ = """Print path of file_ids to a file or directory.
1570
1598
This prints one line for each directory down to the target,
1571
1599
starting at the branch root.
1633
1661
class cmd_ancestry(Command):
1634
"""List all revisions merged into this branch."""
1662
__doc__ = """List all revisions merged into this branch."""
1636
1664
_see_also = ['log', 'revision-history']
1637
1665
takes_args = ['location?']
1767
1795
class cmd_init_repository(Command):
1768
"""Create a shared repository for branches to share storage space.
1796
__doc__ = """Create a shared repository for branches to share storage space.
1770
1798
New branches created under the repository directory will store their
1771
1799
revisions in the repository, not in the branch directory. For branches
1827
1855
class cmd_diff(Command):
1828
"""Show differences in the working tree, between revisions or branches.
1856
__doc__ = """Show differences in the working tree, between revisions or branches.
1830
1858
If no arguments are given, all changes for the current tree are listed.
1831
1859
If files are given, only the changes in those files are listed.
1917
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'),
1921
1953
aliases = ['di', 'dif']
1922
1954
encoding_type = 'exact'
1924
1956
@display_command
1925
1957
def run(self, revision=None, file_list=None, diff_options=None,
1926
prefix=None, old=None, new=None, using=None):
1927
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,
1929
1962
if (prefix is None) or (prefix == '0'):
1930
1963
# diff -p0 format
1944
1977
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1945
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 '
1947
1984
(old_tree, new_tree,
1948
1985
old_branch, new_branch,
1949
specific_files, extra_trees) = get_trees_and_branches_to_diff(
1950
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)
1951
1988
return show_diff_trees(old_tree, new_tree, sys.stdout,
1952
1989
specific_files=specific_files,
1953
1990
external_diff_options=diff_options,
1954
1991
old_label=old_label, new_label=new_label,
1955
extra_trees=extra_trees, using=using)
1992
extra_trees=extra_trees, using=using,
1958
1996
class cmd_deleted(Command):
1959
"""List files deleted in the working tree.
1997
__doc__ = """List files deleted in the working tree.
1961
1999
# TODO: Show files deleted since a previous revision, or
1962
2000
# between two revisions.
2261
2299
help='Show changes made in each revision as a patch.'),
2262
2300
Option('include-merges',
2263
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)'
2265
2307
encoding_type = 'replace'
2278
2320
show_diff=False,
2279
include_merges=False):
2321
include_merges=False,
2322
exclude_common_ancestry=False,
2280
2324
from bzrlib.log import (
2282
2326
make_log_request_dict,
2283
2327
_get_info_for_log_files,
2285
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')
2286
2334
if include_merges:
2287
2335
if levels is None:
2381
2429
direction=direction, specific_fileids=file_ids,
2382
2430
start_revision=rev1, end_revision=rev2, limit=limit,
2383
2431
message_search=message, delta_type=delta_type,
2384
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,
2385
2435
Logger(b, rqst).show(lf)
2406
2456
raise errors.BzrCommandError(
2407
2457
"bzr %s doesn't accept two revisions in different"
2408
2458
" branches." % command_name)
2409
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)
2410
2464
# Avoid loading all of history when we know a missing
2411
2465
# end of range means the last revision ...
2412
2466
if end_spec.spec is None:
2607
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.
2610
2670
Patterns prefixed with '!' are exceptions to ignore patterns and take
2611
2671
precedence over regular ignores. Such exceptions are used to specify
2612
2672
files that should be versioned which would otherwise be ignored.
2653
2713
_see_also = ['status', 'ignored', 'patterns']
2654
2714
takes_args = ['name_pattern*']
2655
2715
takes_options = [
2656
Option('old-default-rules',
2657
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.')
2660
def run(self, name_pattern_list=None, old_default_rules=None):
2720
def run(self, name_pattern_list=None, default_rules=None):
2661
2721
from bzrlib import ignores
2662
if old_default_rules is not None:
2663
# dump the rules and exit
2664
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)
2667
2727
if not name_pattern_list:
2668
2728
raise errors.BzrCommandError("ignore requires at least one "
2669
"NAME_PATTERN or --old-default-rules")
2729
"NAME_PATTERN or --default-rules.")
2670
2730
name_pattern_list = [globbing.normalize_pattern(p)
2671
2731
for p in name_pattern_list]
2672
2732
for name_pattern in name_pattern_list:
2684
2744
if id is not None:
2685
2745
filename = entry[0]
2686
2746
if ignored.match(filename):
2687
matches.append(filename.encode('utf-8'))
2747
matches.append(filename)
2689
2749
if len(matches) > 0:
2690
print "Warning: the following files are version controlled and" \
2691
" match your ignore pattern:\n%s" \
2692
"\nThese files will continue to be version controlled" \
2693
" 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),))
2696
2756
class cmd_ignored(Command):
2697
"""List ignored files and the patterns that matched them.
2757
__doc__ = """List ignored files and the patterns that matched them.
2699
2759
List all the ignored files and the ignore pattern that caused the file to
2735
2795
revno = int(revno)
2736
2796
except ValueError:
2737
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2739
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)
2742
2803
class cmd_export(Command):
2743
"""Export current or past revision to a destination directory or archive.
2804
__doc__ = """Export current or past revision to a destination directory or archive.
2745
2806
If no revision is specified this exports the last committed revision.
2780
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.'),
2782
2846
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2783
root=None, filters=False):
2847
root=None, filters=False, per_file_timestamps=False):
2784
2848
from bzrlib.export import export
2786
2850
if branch_or_subdir is None:
2794
2858
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2796
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)
2797
2862
except errors.NoSuchExportFormat, e:
2798
2863
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2801
2866
class cmd_cat(Command):
2802
"""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.
2804
2869
If no revision is nominated, the last revision is used.
2887
2952
class cmd_local_time_offset(Command):
2888
"""Show the offset in seconds from GMT to local time."""
2953
__doc__ = """Show the offset in seconds from GMT to local time."""
2890
2955
@display_command
2892
print osutils.local_time_offset()
2957
self.outf.write("%s\n" % osutils.local_time_offset())
2896
2961
class cmd_commit(Command):
2897
"""Commit changes into a new revision.
2962
__doc__ = """Commit changes into a new revision.
2899
2964
An explanatory message needs to be given for each commit. This is
2900
2965
often done by using the --message option (getting the message from the
3008
3073
"the master branch until a normal commit "
3009
3074
"is performed."
3076
Option('show-diff', short_name='p',
3012
3077
help='When no message is supplied, show the diff along'
3013
3078
' with the status summary in the message editor.'),
3094
3159
'(use --file "%(f)s" to take commit message from that file)'
3095
3160
% { 'f': message })
3096
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")
3098
3169
def get_message(commit_obj):
3099
3170
"""Callback to get commit message"""
3100
my_message = message
3101
if my_message is not None and '\r' in my_message:
3102
my_message = my_message.replace('\r\n', '\n')
3103
my_message = my_message.replace('\r', '\n')
3104
if my_message is None and not file:
3105
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,
3106
3180
selected_list, diff=show_diff,
3107
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
3108
3187
start_message = generate_commit_message_template(commit_obj)
3109
my_message = edit_commit_message_encoded(t,
3188
my_message = edit_commit_message_encoded(text,
3110
3189
start_message=start_message)
3111
3190
if my_message is None:
3112
3191
raise errors.BzrCommandError("please specify a commit"
3113
3192
" message with either --message or --file")
3114
elif my_message and file:
3115
raise errors.BzrCommandError(
3116
"please specify either --message or --file")
3118
my_message = codecs.open(file, 'rt',
3119
osutils.get_user_encoding()).read()
3120
3193
if my_message == "":
3121
3194
raise errors.BzrCommandError("empty commit message specified")
3122
3195
return my_message
3134
3207
timezone=offset,
3135
3208
exclude=safe_relpath_files(tree, exclude))
3136
3209
except PointlessCommit:
3137
# FIXME: This should really happen before the file is read in;
3138
# perhaps prepare the commit; get the message; then actually commit
3139
3210
raise errors.BzrCommandError("No changes to commit."
3140
3211
" Use --unchanged to commit anyhow.")
3141
3212
except ConflictsInTree:
3146
3217
raise errors.BzrCommandError("Commit refused because there are"
3147
3218
" unknown files in the working tree.")
3148
3219
except errors.BoundBranchOutOfDate, e:
3149
raise errors.BzrCommandError(str(e) + "\n"
3150
'To commit to master branch, run update and then commit.\n'
3151
'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 '
3155
3227
class cmd_check(Command):
3156
"""Validate working tree structure, branch consistency and repository history.
3228
__doc__ = """Validate working tree structure, branch consistency and repository history.
3158
3230
This command checks various invariants about branch and repository storage
3159
3231
to detect data corruption or bzr bugs.
3318
3390
@display_command
3319
3391
def printme(self, branch):
3392
self.outf.write('%s\n' % branch.nick)
3323
3395
class cmd_alias(Command):
3324
"""Set/unset and display aliases.
3396
__doc__ = """Set/unset and display aliases.
3327
3399
Show the current aliases::
3393
3465
class cmd_selftest(Command):
3394
"""Run internal test suite.
3466
__doc__ = """Run internal test suite.
3396
3468
If arguments are given, they are regular expressions that say which tests
3397
3469
should run. Tests matching any expression are run, and other tests are
3444
3516
from bzrlib.tests import stub_sftp
3445
3517
return stub_sftp.SFTPAbsoluteServer
3446
3518
if typestring == "memory":
3447
from bzrlib.transport.memory import MemoryServer
3519
from bzrlib.tests import test_server
3520
return memory.MemoryServer
3449
3521
if typestring == "fakenfs":
3450
from bzrlib.transport.fakenfs import FakeNFSServer
3451
return FakeNFSServer
3522
from bzrlib.tests import test_server
3523
return test_server.FakeNFSServer
3452
3524
msg = "No known transport type %s. Supported types are: sftp\n" %\
3454
3526
raise errors.BzrCommandError(msg)
3538
3610
raise errors.BzrCommandError("subunit not available. subunit "
3539
3611
"needs to be installed to use --subunit.")
3540
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)
3542
3619
self.additional_selftest_args.setdefault(
3543
3620
'suite_decorators', []).append(parallel)
3593
3670
class cmd_rocks(Command):
3594
"""Statement of optimism."""
3671
__doc__ = """Statement of optimism."""
3598
3675
@display_command
3600
print "It sure does!"
3677
self.outf.write("It sure does!\n")
3603
3680
class cmd_find_merge_base(Command):
3604
"""Find and print a base revision for merging two branches."""
3681
__doc__ = """Find and print a base revision for merging two branches."""
3605
3682
# TODO: Options to specify revisions on either side, as if
3606
3683
# merging only part of the history.
3607
3684
takes_args = ['branch', 'other']
3623
3700
graph = branch1.repository.get_graph(branch2.repository)
3624
3701
base_rev_id = graph.find_unique_lca(last1, last2)
3626
print 'merge base is revision %s' % base_rev_id
3703
self.outf.write('merge base is revision %s\n' % base_rev_id)
3629
3706
class cmd_merge(Command):
3630
"""Perform a three-way merge.
3707
__doc__ = """Perform a three-way merge.
3632
3709
The source of the merge can be specified either in the form of a branch,
3633
3710
or in the form of a path to a file containing a merge directive generated
4020
4097
def run(self, file_list=None, merge_type=None, show_base=False,
4021
4098
reprocess=False):
4099
from bzrlib.conflicts import restore
4022
4100
if merge_type is None:
4023
4101
merge_type = _mod_merge.Merge3Merger
4024
4102
tree, file_list = tree_files(file_list)
4084
4162
class cmd_revert(Command):
4085
"""Revert files to a previous revision.
4163
__doc__ = """Revert files to a previous revision.
4087
4165
Giving a list of files will revert only those files. Otherwise, all files
4088
4166
will be reverted. If the revision is not specified with '--revision', the
4139
4217
def run(self, revision=None, no_backup=False, file_list=None,
4140
4218
forget_merges=None):
4141
4219
tree, file_list = tree_files(file_list)
4220
tree.lock_tree_write()
4143
4221
self.add_cleanup(tree.unlock)
4144
4222
if forget_merges:
4145
4223
tree.set_parent_ids(tree.get_parent_ids()[:1])
4296
4377
remote_branch = Branch.open(other_branch)
4297
4378
if remote_branch.base == local_branch.base:
4298
4379
remote_branch = local_branch
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4300
local_branch.lock_read()
4301
self.add_cleanup(local_branch.unlock)
4302
4384
local_revid_range = _revision_range_to_revid_range(
4303
4385
_get_revision_range(my_revision, local_branch,
4306
remote_branch.lock_read()
4307
self.add_cleanup(remote_branch.unlock)
4308
4388
remote_revid_range = _revision_range_to_revid_range(
4309
4389
_get_revision_range(revision,
4310
4390
remote_branch, self.name()))
4371
4451
class cmd_pack(Command):
4372
"""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.
4374
4470
_see_also = ['repositories']
4375
4471
takes_args = ['branch_or_repo?']
4473
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4377
def run(self, branch_or_repo='.'):
4476
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4378
4477
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4380
4479
branch = dir.open_branch()
4381
4480
repository = branch.repository
4382
4481
except errors.NotBranchError:
4383
4482
repository = dir.open_repository()
4483
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4387
4486
class cmd_plugins(Command):
4388
"""List the installed plugins.
4487
__doc__ = """List the installed plugins.
4390
4489
This command displays the list of installed plugins including
4391
4490
version of plugin and a short description of each.
4422
4521
doc = '(no description)'
4423
4522
result.append((name_ver, doc, plugin.path()))
4424
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")
4432
4531
class cmd_testament(Command):
4433
"""Show testament (signing-form) of a revision."""
4532
__doc__ = """Show testament (signing-form) of a revision."""
4434
4533
takes_options = [
4436
4535
Option('long', help='Produce long-format testament.'),
4464
4563
class cmd_annotate(Command):
4465
"""Show the origin of each line in a file.
4564
__doc__ = """Show the origin of each line in a file.
4467
4566
This prints out the given file with an annotation on the left side
4468
4567
indicating which revision, author and date introduced the change.
4583
4682
class cmd_bind(Command):
4584
"""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.
4586
4686
Once converted into a checkout, commits must succeed on the master branch
4587
4687
before they will be applied to the local branch.
4623
4723
class cmd_unbind(Command):
4624
"""Convert the current checkout into a regular branch.
4724
__doc__ = """Convert the current checkout into a regular branch.
4626
4726
After unbinding, the local branch is considered independent and subsequent
4627
4727
commits will be local only.
4640
4740
class cmd_uncommit(Command):
4641
"""Remove the last committed revision.
4741
__doc__ = """Remove the last committed revision.
4643
4743
--verbose will print out what is being removed.
4644
4744
--dry-run will go through all the motions, but not actually
4712
4812
rev_id = b.get_rev_id(revno)
4714
4814
if rev_id is None or _mod_revision.is_null(rev_id):
4715
ui.ui_factory.note('No revisions to uncommit.')
4815
self.outf.write('No revisions to uncommit.\n')
4718
log_collector = ui.ui_factory.make_output_stream()
4719
4818
lf = log_formatter('short',
4720
to_file=log_collector,
4721
4820
show_timezone='original')
4728
4827
end_revision=last_revno)
4731
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')
4733
ui.ui_factory.note('The above revision(s) will be removed.')
4833
self.outf.write('The above revision(s) will be removed.\n')
4736
if not ui.ui_factory.get_boolean('Are you sure [y/N]? '):
4737
ui.ui_factory.note('Canceled')
4836
if not ui.ui_factory.get_boolean('Are you sure'):
4837
self.outf.write('Canceled')
4740
4840
mutter('Uncommitting from {%s} to {%s}',
4741
4841
last_rev_id, rev_id)
4742
4842
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4743
4843
revno=revno, local=local)
4744
ui.ui_factory.note('You can restore the old tip by running:\n'
4745
' 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)
4748
4848
class cmd_break_lock(Command):
4749
"""Break a dead lock on a repository, branch or working directory.
4849
__doc__ = """Break a dead lock on a repository, branch or working directory.
4751
4851
CAUTION: Locks should only be broken when you are sure that the process
4752
4852
holding the lock has been stopped.
4899
4999
class cmd_split(Command):
4900
"""Split a subdirectory of a tree into a separate tree.
5000
__doc__ = """Split a subdirectory of a tree into a separate tree.
4902
5002
This command will produce a target tree in a format that supports
4903
5003
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4925
5025
class cmd_merge_directive(Command):
4926
"""Generate a merge directive for auto-merge tools.
5026
__doc__ = """Generate a merge directive for auto-merge tools.
4928
5028
A directive requests a merge to be performed, and also provides all the
4929
5029
information necessary to do so. This means it must either include a
5214
5314
class cmd_tag(Command):
5215
"""Create, remove or modify a tag naming a revision.
5315
__doc__ = """Create, remove or modify a tag naming a revision.
5217
5317
Tags give human-meaningful names to revisions. Commands that take a -r
5218
5318
(--revision) option can be given -rtag:X, where X is any previously
5227
5327
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5228
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
5231
5336
_see_also = ['commit', 'tags']
5232
takes_args = ['tag_name']
5337
takes_args = ['tag_name?']
5233
5338
takes_options = [
5234
5339
Option('delete',
5235
5340
help='Delete this tag rather than placing it.',
5266
5373
revision_id = revision[0].as_revision_id(branch)
5268
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.")
5269
5381
if (not force) and branch.tags.has_tag(tag_name):
5270
5382
raise errors.TagAlreadyExists(tag_name)
5271
5383
branch.tags.set_tag(tag_name, revision_id)
5440
5552
class cmd_switch(Command):
5441
"""Set the branch of a checkout and update.
5553
__doc__ = """Set the branch of a checkout and update.
5443
5555
For lightweight checkouts, this changes the branch being referenced.
5444
5556
For heavyweight checkouts, this checks that there are no local commits
5707
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()
5710
5847
class cmd_shelve(Command):
5711
"""Temporarily set aside some changes from the current tree.
5848
__doc__ = """Temporarily set aside some changes from the current tree.
5713
5850
Shelve allows you to temporarily put changes you've made "on the shelf",
5714
5851
ie. out of the way, until a later time when you can bring them back from
5785
5922
class cmd_unshelve(Command):
5786
"""Restore shelved changes.
5923
__doc__ = """Restore shelved changes.
5788
5925
By default, the most recently shelved changes are restored. However if you
5789
5926
specify a shelf by id those changes will be restored instead. This works
5817
5954
class cmd_clean_tree(Command):
5818
"""Remove unwanted files from working tree.
5955
__doc__ = """Remove unwanted files from working tree.
5820
5957
By default, only unknown files, not ignored files, are deleted. Versioned
5821
5958
files are never deleted.
5851
5988
class cmd_reference(Command):
5852
"""list, view and set branch locations for nested trees.
5989
__doc__ = """list, view and set branch locations for nested trees.
5854
5991
If no arguments are provided, lists the branch locations for nested trees.
5855
5992
If one argument is provided, display the branch location for that tree.
5895
6032
self.outf.write('%s %s\n' % (path, location))
5898
# these get imported and then picked up by the scan for cmd_*
5899
# TODO: Some more consistent way to split command definitions across files;
5900
# we do need to load at least some information about them to know of
5901
# aliases. ideally we would avoid loading the implementation until the
5902
# details were needed.
5903
from bzrlib.cmd_version_info import cmd_version_info
5904
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5905
from bzrlib.bundle.commands import (
5908
from bzrlib.foreign import cmd_dpush
5909
from bzrlib.sign_my_commits import cmd_sign_my_commits
5910
from bzrlib.weave_commands import cmd_versionedfile_list, \
5911
cmd_weave_plan_merge, cmd_weave_merge_text
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)