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.
2191
2229
:Tips & tricks:
2193
2231
GUI tools and IDEs are often better at exploring history than command
2194
line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2195
respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2196
http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2198
Web interfaces are often better at exploring history than command line
2199
tools, particularly for branches on servers. You may prefer Loggerhead
2200
or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2232
line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2233
bzr-explorer shell, or the Loggerhead web interface. See the Plugin
2234
Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2235
<http://wiki.bazaar.canonical.com/IDEIntegration>.
2202
2237
You may find it useful to add the aliases below to ``bazaar.conf``::
2264
2299
help='Show changes made in each revision as a patch.'),
2265
2300
Option('include-merges',
2266
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)'
2268
2307
encoding_type = 'replace'
2281
2320
show_diff=False,
2282
include_merges=False):
2321
include_merges=False,
2322
exclude_common_ancestry=False,
2283
2324
from bzrlib.log import (
2285
2326
make_log_request_dict,
2286
2327
_get_info_for_log_files,
2288
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')
2289
2334
if include_merges:
2290
2335
if levels is None:
2384
2429
direction=direction, specific_fileids=file_ids,
2385
2430
start_revision=rev1, end_revision=rev2, limit=limit,
2386
2431
message_search=message, delta_type=delta_type,
2387
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,
2388
2435
Logger(b, rqst).show(lf)
2409
2456
raise errors.BzrCommandError(
2410
2457
"bzr %s doesn't accept two revisions in different"
2411
2458
" branches." % command_name)
2412
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)
2413
2464
# Avoid loading all of history when we know a missing
2414
2465
# end of range means the last revision ...
2415
2466
if end_spec.spec is None:
2609
2660
After adding, editing or deleting that file either indirectly by
2610
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.
2670
Patterns prefixed with '!' are exceptions to ignore patterns and take
2671
precedence over regular ignores. Such exceptions are used to specify
2672
files that should be versioned which would otherwise be ignored.
2674
Patterns prefixed with '!!' act as regular ignore patterns, but have
2675
precedence over the '!' exception patterns.
2613
2677
Note: ignore patterns containing shell wildcards must be quoted from
2614
2678
the shell on Unix.
2633
2701
Ignore everything but the "debian" toplevel directory::
2635
2703
bzr ignore "RE:(?!debian/).*"
2705
Ignore everything except the "local" toplevel directory,
2706
but always ignore "*~" autosave files, even under local/::
2709
bzr ignore "!./local"
2638
2713
_see_also = ['status', 'ignored', 'patterns']
2639
2714
takes_args = ['name_pattern*']
2640
2715
takes_options = [
2641
Option('old-default-rules',
2642
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.')
2645
def run(self, name_pattern_list=None, old_default_rules=None):
2720
def run(self, name_pattern_list=None, default_rules=None):
2646
2721
from bzrlib import ignores
2647
if old_default_rules is not None:
2648
# dump the rules and exit
2649
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)
2652
2727
if not name_pattern_list:
2653
2728
raise errors.BzrCommandError("ignore requires at least one "
2654
"NAME_PATTERN or --old-default-rules")
2729
"NAME_PATTERN or --default-rules.")
2655
2730
name_pattern_list = [globbing.normalize_pattern(p)
2656
2731
for p in name_pattern_list]
2657
2732
for name_pattern in name_pattern_list:
2669
2744
if id is not None:
2670
2745
filename = entry[0]
2671
2746
if ignored.match(filename):
2672
matches.append(filename.encode('utf-8'))
2747
matches.append(filename)
2674
2749
if len(matches) > 0:
2675
print "Warning: the following files are version controlled and" \
2676
" match your ignore pattern:\n%s" \
2677
"\nThese files will continue to be version controlled" \
2678
" 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),))
2681
2756
class cmd_ignored(Command):
2682
"""List ignored files and the patterns that matched them.
2757
__doc__ = """List ignored files and the patterns that matched them.
2684
2759
List all the ignored files and the ignore pattern that caused the file to
2720
2795
revno = int(revno)
2721
2796
except ValueError:
2722
raise errors.BzrCommandError("not a valid revision-number: %r" % revno)
2724
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)
2727
2803
class cmd_export(Command):
2728
"""Export current or past revision to a destination directory or archive.
2804
__doc__ = """Export current or past revision to a destination directory or archive.
2730
2806
If no revision is specified this exports the last committed revision.
2765
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.'),
2767
2846
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2768
root=None, filters=False):
2847
root=None, filters=False, per_file_timestamps=False):
2769
2848
from bzrlib.export import export
2771
2850
if branch_or_subdir is None:
2779
2858
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2781
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)
2782
2862
except errors.NoSuchExportFormat, e:
2783
2863
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2786
2866
class cmd_cat(Command):
2787
"""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.
2789
2869
If no revision is nominated, the last revision is used.
2872
2952
class cmd_local_time_offset(Command):
2873
"""Show the offset in seconds from GMT to local time."""
2953
__doc__ = """Show the offset in seconds from GMT to local time."""
2875
2955
@display_command
2877
print osutils.local_time_offset()
2957
self.outf.write("%s\n" % osutils.local_time_offset())
2881
2961
class cmd_commit(Command):
2882
"""Commit changes into a new revision.
2962
__doc__ = """Commit changes into a new revision.
2884
2964
An explanatory message needs to be given for each commit. This is
2885
2965
often done by using the --message option (getting the message from the
2993
3073
"the master branch until a normal commit "
2994
3074
"is performed."
3076
Option('show-diff', short_name='p',
2997
3077
help='When no message is supplied, show the diff along'
2998
3078
' with the status summary in the message editor.'),
3079
3159
'(use --file "%(f)s" to take commit message from that file)'
3080
3160
% { 'f': message })
3081
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")
3083
3169
def get_message(commit_obj):
3084
3170
"""Callback to get commit message"""
3085
my_message = message
3086
if my_message is not None and '\r' in my_message:
3087
my_message = my_message.replace('\r\n', '\n')
3088
my_message = my_message.replace('\r', '\n')
3089
if my_message is None and not file:
3090
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,
3091
3180
selected_list, diff=show_diff,
3092
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
3093
3187
start_message = generate_commit_message_template(commit_obj)
3094
my_message = edit_commit_message_encoded(t,
3188
my_message = edit_commit_message_encoded(text,
3095
3189
start_message=start_message)
3096
3190
if my_message is None:
3097
3191
raise errors.BzrCommandError("please specify a commit"
3098
3192
" message with either --message or --file")
3099
elif my_message and file:
3100
raise errors.BzrCommandError(
3101
"please specify either --message or --file")
3103
my_message = codecs.open(file, 'rt',
3104
osutils.get_user_encoding()).read()
3105
3193
if my_message == "":
3106
3194
raise errors.BzrCommandError("empty commit message specified")
3107
3195
return my_message
3119
3207
timezone=offset,
3120
3208
exclude=safe_relpath_files(tree, exclude))
3121
3209
except PointlessCommit:
3122
# FIXME: This should really happen before the file is read in;
3123
# perhaps prepare the commit; get the message; then actually commit
3124
3210
raise errors.BzrCommandError("No changes to commit."
3125
3211
" Use --unchanged to commit anyhow.")
3126
3212
except ConflictsInTree:
3131
3217
raise errors.BzrCommandError("Commit refused because there are"
3132
3218
" unknown files in the working tree.")
3133
3219
except errors.BoundBranchOutOfDate, e:
3134
raise errors.BzrCommandError(str(e) + "\n"
3135
'To commit to master branch, run update and then commit.\n'
3136
'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 '
3140
3227
class cmd_check(Command):
3141
"""Validate working tree structure, branch consistency and repository history.
3228
__doc__ = """Validate working tree structure, branch consistency and repository history.
3143
3230
This command checks various invariants about branch and repository storage
3144
3231
to detect data corruption or bzr bugs.
3303
3390
@display_command
3304
3391
def printme(self, branch):
3392
self.outf.write('%s\n' % branch.nick)
3308
3395
class cmd_alias(Command):
3309
"""Set/unset and display aliases.
3396
__doc__ = """Set/unset and display aliases.
3312
3399
Show the current aliases::
3378
3465
class cmd_selftest(Command):
3379
"""Run internal test suite.
3466
__doc__ = """Run internal test suite.
3381
3468
If arguments are given, they are regular expressions that say which tests
3382
3469
should run. Tests matching any expression are run, and other tests are
3426
3513
def get_transport_type(typestring):
3427
3514
"""Parse and return a transport specifier."""
3428
3515
if typestring == "sftp":
3429
from bzrlib.transport.sftp import SFTPAbsoluteServer
3430
return SFTPAbsoluteServer
3516
from bzrlib.tests import stub_sftp
3517
return stub_sftp.SFTPAbsoluteServer
3431
3518
if typestring == "memory":
3432
from bzrlib.transport.memory import MemoryServer
3519
from bzrlib.tests import test_server
3520
return memory.MemoryServer
3434
3521
if typestring == "fakenfs":
3435
from bzrlib.transport.fakenfs import FakeNFSServer
3436
return FakeNFSServer
3522
from bzrlib.tests import test_server
3523
return test_server.FakeNFSServer
3437
3524
msg = "No known transport type %s. Supported types are: sftp\n" %\
3439
3526
raise errors.BzrCommandError(msg)
3523
3610
raise errors.BzrCommandError("subunit not available. subunit "
3524
3611
"needs to be installed to use --subunit.")
3525
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)
3527
3619
self.additional_selftest_args.setdefault(
3528
3620
'suite_decorators', []).append(parallel)
3578
3670
class cmd_rocks(Command):
3579
"""Statement of optimism."""
3671
__doc__ = """Statement of optimism."""
3583
3675
@display_command
3585
print "It sure does!"
3677
self.outf.write("It sure does!\n")
3588
3680
class cmd_find_merge_base(Command):
3589
"""Find and print a base revision for merging two branches."""
3681
__doc__ = """Find and print a base revision for merging two branches."""
3590
3682
# TODO: Options to specify revisions on either side, as if
3591
3683
# merging only part of the history.
3592
3684
takes_args = ['branch', 'other']
3608
3700
graph = branch1.repository.get_graph(branch2.repository)
3609
3701
base_rev_id = graph.find_unique_lca(last1, last2)
3611
print 'merge base is revision %s' % base_rev_id
3703
self.outf.write('merge base is revision %s\n' % base_rev_id)
3614
3706
class cmd_merge(Command):
3615
"""Perform a three-way merge.
3707
__doc__ = """Perform a three-way merge.
3617
3709
The source of the merge can be specified either in the form of a branch,
3618
3710
or in the form of a path to a file containing a merge directive generated
3647
3739
committed to record the result of the merge.
3649
3741
merge refuses to run if there are any uncommitted changes, unless
3742
--force is given. The --force option can also be used to create a
3743
merge revision which has more than two parents.
3652
3745
If one would like to merge changes from the working tree of the other
3653
3746
branch without merging any committed revisions, the --uncommitted option
3754
3854
raise errors.BzrCommandError(
3755
3855
'Cannot use -r with merge directives or bundles')
3756
3856
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3759
3859
if merger is None and uncommitted:
3760
3860
if revision is not None and len(revision) > 0:
3761
3861
raise errors.BzrCommandError('Cannot use --uncommitted and'
3762
3862
' --revision at the same time.')
3763
merger = self.get_merger_from_uncommitted(tree, location, pb)
3863
merger = self.get_merger_from_uncommitted(tree, location, None)
3764
3864
allow_pending = False
3766
3866
if merger is None:
3767
3867
merger, allow_pending = self._get_merger_from_branch(tree,
3768
location, revision, remember, possible_transports, pb)
3868
location, revision, remember, possible_transports, None)
3770
3870
merger.merge_type = merge_type
3771
3871
merger.reprocess = reprocess
3997
4097
def run(self, file_list=None, merge_type=None, show_base=False,
3998
4098
reprocess=False):
4099
from bzrlib.conflicts import restore
3999
4100
if merge_type is None:
4000
4101
merge_type = _mod_merge.Merge3Merger
4001
4102
tree, file_list = tree_files(file_list)
4042
4143
# list, we imply that the working tree text has seen and rejected
4043
4144
# all the changes from the other tree, when in fact those changes
4044
4145
# have not yet been seen.
4045
pb = ui.ui_factory.nested_progress_bar()
4046
4146
tree.set_parent_ids(parents[:1])
4048
merger = _mod_merge.Merger.from_revision_ids(pb,
4148
merger = _mod_merge.Merger.from_revision_ids(None, tree, parents[1])
4050
4149
merger.interesting_ids = interesting_ids
4051
4150
merger.merge_type = merge_type
4052
4151
merger.show_base = show_base
4064
4162
class cmd_revert(Command):
4065
"""Revert files to a previous revision.
4163
__doc__ = """Revert files to a previous revision.
4067
4165
Giving a list of files will revert only those files. Otherwise, all files
4068
4166
will be reverted. If the revision is not specified with '--revision', the
4119
4217
def run(self, revision=None, no_backup=False, file_list=None,
4120
4218
forget_merges=None):
4121
4219
tree, file_list = tree_files(file_list)
4220
tree.lock_tree_write()
4123
4221
self.add_cleanup(tree.unlock)
4124
4222
if forget_merges:
4125
4223
tree.set_parent_ids(tree.get_parent_ids()[:1])
4130
4228
def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4131
4229
rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4132
pb = ui.ui_factory.nested_progress_bar()
4134
tree.revert(file_list, rev_tree, not no_backup, pb,
4135
report_changes=True)
4230
tree.revert(file_list, rev_tree, not no_backup, None,
4231
report_changes=True)
4140
4234
class cmd_assert_fail(Command):
4141
"""Test reporting of assertion failures"""
4235
__doc__ = """Test reporting of assertion failures"""
4142
4236
# intended just for use in testing
4280
4377
remote_branch = Branch.open(other_branch)
4281
4378
if remote_branch.base == local_branch.base:
4282
4379
remote_branch = local_branch
4381
remote_branch.lock_read()
4382
self.add_cleanup(remote_branch.unlock)
4284
local_branch.lock_read()
4285
self.add_cleanup(local_branch.unlock)
4286
4384
local_revid_range = _revision_range_to_revid_range(
4287
4385
_get_revision_range(my_revision, local_branch,
4290
remote_branch.lock_read()
4291
self.add_cleanup(remote_branch.unlock)
4292
4388
remote_revid_range = _revision_range_to_revid_range(
4293
4389
_get_revision_range(revision,
4294
4390
remote_branch, self.name()))
4355
4451
class cmd_pack(Command):
4356
"""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.
4358
4470
_see_also = ['repositories']
4359
4471
takes_args = ['branch_or_repo?']
4473
Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
4361
def run(self, branch_or_repo='.'):
4476
def run(self, branch_or_repo='.', clean_obsolete_packs=False):
4362
4477
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
4364
4479
branch = dir.open_branch()
4365
4480
repository = branch.repository
4366
4481
except errors.NotBranchError:
4367
4482
repository = dir.open_repository()
4483
repository.pack(clean_obsolete_packs=clean_obsolete_packs)
4371
4486
class cmd_plugins(Command):
4372
"""List the installed plugins.
4487
__doc__ = """List the installed plugins.
4374
4489
This command displays the list of installed plugins including
4375
4490
version of plugin and a short description of each.
4382
4497
adding new commands, providing additional network transports and
4383
4498
customizing log output.
4385
See the Bazaar web site, http://bazaar-vcs.org, for further
4386
information on plugins including where to find them and how to
4387
install them. Instructions are also provided there on how to
4388
write new plugins using the Python programming language.
4500
See the Bazaar Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/>
4501
for further information on plugins including where to find them and how to
4502
install them. Instructions are also provided there on how to write new
4503
plugins using the Python programming language.
4390
4505
takes_options = ['verbose']
4406
4521
doc = '(no description)'
4407
4522
result.append((name_ver, doc, plugin.path()))
4408
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")
4416
4531
class cmd_testament(Command):
4417
"""Show testament (signing-form) of a revision."""
4532
__doc__ = """Show testament (signing-form) of a revision."""
4418
4533
takes_options = [
4420
4535
Option('long', help='Produce long-format testament.'),
4448
4563
class cmd_annotate(Command):
4449
"""Show the origin of each line in a file.
4564
__doc__ = """Show the origin of each line in a file.
4451
4566
This prints out the given file with an annotation on the left side
4452
4567
indicating which revision, author and date introduced the change.
4567
4682
class cmd_bind(Command):
4568
"""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.
4570
4686
Once converted into a checkout, commits must succeed on the master branch
4571
4687
before they will be applied to the local branch.
4589
4705
'This format does not remember old locations.')
4591
4707
if location is None:
4592
raise errors.BzrCommandError('No location supplied and no '
4593
'previous location known')
4708
if b.get_bound_location() is not None:
4709
raise errors.BzrCommandError('Branch is already bound')
4711
raise errors.BzrCommandError('No location supplied '
4712
'and no previous location known')
4594
4713
b_other = Branch.open(location)
4596
4715
b.bind(b_other)
4604
4723
class cmd_unbind(Command):
4605
"""Convert the current checkout into a regular branch.
4724
__doc__ = """Convert the current checkout into a regular branch.
4607
4726
After unbinding, the local branch is considered independent and subsequent
4608
4727
commits will be local only.
4621
4740
class cmd_uncommit(Command):
4622
"""Remove the last committed revision.
4741
__doc__ = """Remove the last committed revision.
4624
4743
--verbose will print out what is being removed.
4625
4744
--dry-run will go through all the motions, but not actually
4708
4827
end_revision=last_revno)
4711
print 'Dry-run, pretending to remove the above revisions.'
4713
val = raw_input('Press <enter> to continue')
4830
self.outf.write('Dry-run, pretending to remove'
4831
' the above revisions.\n')
4715
print 'The above revision(s) will be removed.'
4717
val = raw_input('Are you sure [y/N]? ')
4718
if val.lower() not in ('y', 'yes'):
4833
self.outf.write('The above revision(s) will be removed.\n')
4836
if not ui.ui_factory.get_boolean('Are you sure'):
4837
self.outf.write('Canceled')
4722
4840
mutter('Uncommitting from {%s} to {%s}',
4723
4841
last_rev_id, rev_id)
4724
4842
uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
4725
4843
revno=revno, local=local)
4726
note('You can restore the old tip by running:\n'
4727
' 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)
4730
4848
class cmd_break_lock(Command):
4731
"""Break a dead lock on a repository, branch or working directory.
4849
__doc__ = """Break a dead lock on a repository, branch or working directory.
4733
4851
CAUTION: Locks should only be broken when you are sure that the process
4734
4852
holding the lock has been stopped.
4881
4999
class cmd_split(Command):
4882
"""Split a subdirectory of a tree into a separate tree.
5000
__doc__ = """Split a subdirectory of a tree into a separate tree.
4884
5002
This command will produce a target tree in a format that supports
4885
5003
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
4907
5025
class cmd_merge_directive(Command):
4908
"""Generate a merge directive for auto-merge tools.
5026
__doc__ = """Generate a merge directive for auto-merge tools.
4910
5028
A directive requests a merge to be performed, and also provides all the
4911
5029
information necessary to do so. This means it must either include a
5196
5314
class cmd_tag(Command):
5197
"""Create, remove or modify a tag naming a revision.
5315
__doc__ = """Create, remove or modify a tag naming a revision.
5199
5317
Tags give human-meaningful names to revisions. Commands that take a -r
5200
5318
(--revision) option can be given -rtag:X, where X is any previously
5209
5327
To rename a tag (change the name but keep it on the same revsion), run ``bzr
5210
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
5213
5336
_see_also = ['commit', 'tags']
5214
takes_args = ['tag_name']
5337
takes_args = ['tag_name?']
5215
5338
takes_options = [
5216
5339
Option('delete',
5217
5340
help='Delete this tag rather than placing it.',
5248
5373
revision_id = revision[0].as_revision_id(branch)
5250
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.")
5251
5381
if (not force) and branch.tags.has_tag(tag_name):
5252
5382
raise errors.TagAlreadyExists(tag_name)
5253
5383
branch.tags.set_tag(tag_name, revision_id)
5422
5552
class cmd_switch(Command):
5423
"""Set the branch of a checkout and update.
5553
__doc__ = """Set the branch of a checkout and update.
5425
5555
For lightweight checkouts, this changes the branch being referenced.
5426
5556
For heavyweight checkouts, this checks that there are no local commits
5689
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()
5692
5847
class cmd_shelve(Command):
5693
"""Temporarily set aside some changes from the current tree.
5848
__doc__ = """Temporarily set aside some changes from the current tree.
5695
5850
Shelve allows you to temporarily put changes you've made "on the shelf",
5696
5851
ie. out of the way, until a later time when you can bring them back from
5767
5922
class cmd_unshelve(Command):
5768
"""Restore shelved changes.
5923
__doc__ = """Restore shelved changes.
5770
5925
By default, the most recently shelved changes are restored. However if you
5771
5926
specify a shelf by id those changes will be restored instead. This works
5799
5954
class cmd_clean_tree(Command):
5800
"""Remove unwanted files from working tree.
5955
__doc__ = """Remove unwanted files from working tree.
5802
5957
By default, only unknown files, not ignored files, are deleted. Versioned
5803
5958
files are never deleted.
5833
5988
class cmd_reference(Command):
5834
"""list, view and set branch locations for nested trees.
5989
__doc__ = """list, view and set branch locations for nested trees.
5836
5991
If no arguments are provided, lists the branch locations for nested trees.
5837
5992
If one argument is provided, display the branch location for that tree.
5877
6032
self.outf.write('%s %s\n' % (path, location))
5880
# these get imported and then picked up by the scan for cmd_*
5881
# TODO: Some more consistent way to split command definitions across files;
5882
# we do need to load at least some information about them to know of
5883
# aliases. ideally we would avoid loading the implementation until the
5884
# details were needed.
5885
from bzrlib.cmd_version_info import cmd_version_info
5886
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
5887
from bzrlib.bundle.commands import (
5890
from bzrlib.foreign import cmd_dpush
5891
from bzrlib.sign_my_commits import cmd_sign_my_commits
5892
from bzrlib.weave_commands import cmd_versionedfile_list, \
5893
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)