17
17
"""builtin bzr commands"""
20
from StringIO import StringIO
22
from bzrlib.lazy_import import lazy_import
23
lazy_import(globals(), """
27
31
from bzrlib import (
41
from bzrlib.branch import Branch, BranchReferenceFormat
42
from bzrlib.bundle import read_bundle_from_url
54
from bzrlib.branch import Branch
43
55
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
44
56
from bzrlib.conflicts import ConflictList
57
from bzrlib.revisionspec import RevisionSpec
58
from bzrlib.smtp_connection import SMTPConnection
59
from bzrlib.workingtree import WorkingTree
45
62
from bzrlib.commands import Command, display_command
46
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
47
NotBranchError, DivergedBranches, NotConflicted,
48
NoSuchFile, NoWorkingTree, FileInWrongBranch,
49
NotVersionedError, NotABundle)
50
from bzrlib.merge import Merge3Merger
51
from bzrlib.option import Option
63
from bzrlib.option import ListOption, Option, RegistryOption
52
64
from bzrlib.progress import DummyProgress, ProgressPhase
53
from bzrlib.revision import common_ancestor
54
from bzrlib.revisionspec import RevisionSpec
55
65
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
56
from bzrlib.transport.local import LocalTransport
58
from bzrlib.workingtree import WorkingTree
61
68
def tree_files(file_list, default_branch=u'.'):
63
70
return internal_tree_files(file_list, default_branch)
64
except FileInWrongBranch, e:
65
raise BzrCommandError("%s is not in the same branch as %s" %
66
(e.path, file_list[0]))
71
except errors.FileInWrongBranch, e:
72
raise errors.BzrCommandError("%s is not in the same branch as %s" %
73
(e.path, file_list[0]))
69
76
# XXX: Bad function name; should possibly also be a class method of
79
86
:param file_list: Filenames to convert.
81
:param default_branch: Fallback tree path to use if file_list is empty or None.
88
:param default_branch: Fallback tree path to use if file_list is empty or
83
91
:return: workingtree, [relative_paths]
85
93
if file_list is None or len(file_list) == 0:
86
94
return WorkingTree.open_containing(default_branch)[0], file_list
87
tree = WorkingTree.open_containing(file_list[0])[0]
95
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
89
97
for filename in file_list:
91
new_list.append(tree.relpath(filename))
99
new_list.append(tree.relpath(osutils.dereference_path(filename)))
92
100
except errors.PathNotChild:
93
raise FileInWrongBranch(tree.branch, filename)
101
raise errors.FileInWrongBranch(tree.branch, filename)
94
102
return tree, new_list
105
@symbol_versioning.deprecated_function(symbol_versioning.zero_fifteen)
97
106
def get_format_type(typestring):
98
107
"""Parse and return a format specifier."""
99
if typestring == "weave":
100
return bzrdir.BzrDirFormat6()
108
# Have to use BzrDirMetaFormat1 directly, so that
109
# RepositoryFormat.set_default_format works
101
110
if typestring == "default":
102
111
return bzrdir.BzrDirMetaFormat1()
103
if typestring == "metaweave":
104
format = bzrdir.BzrDirMetaFormat1()
105
format.repository_format = repository.RepositoryFormat7()
107
if typestring == "knit":
108
format = bzrdir.BzrDirMetaFormat1()
109
format.repository_format = repository.RepositoryFormatKnit1()
111
if typestring == "experimental-knit2":
112
format = bzrdir.BzrDirMetaFormat1()
113
format.repository_format = repository.RepositoryFormatKnit2()
115
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
116
"metaweave and weave" % typestring
117
raise BzrCommandError(msg)
113
return bzrdir.format_registry.make_bzrdir(typestring)
115
msg = 'Unknown bzr format "%s". See "bzr help formats".' % typestring
116
raise errors.BzrCommandError(msg)
120
119
# TODO: Make sure no commands unconditionally use the working directory as a
368
446
set. For example: bzr inventory --show-ids this/file
371
451
takes_options = ['revision', 'show-ids', 'kind']
372
452
takes_args = ['file*']
375
455
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
376
456
if kind and kind not in ['file', 'directory', 'symlink']:
377
raise BzrCommandError('invalid kind specified')
457
raise errors.BzrCommandError('invalid kind specified')
379
459
work_tree, file_list = tree_files(file_list)
381
if revision is not None:
382
if len(revision) > 1:
383
raise BzrCommandError('bzr inventory --revision takes'
384
' exactly one revision identifier')
385
revision_id = revision[0].in_history(work_tree.branch).rev_id
386
tree = work_tree.branch.repository.revision_tree(revision_id)
388
# We include work_tree as well as 'tree' here
389
# So that doing '-r 10 path/foo' will lookup whatever file
390
# exists now at 'path/foo' even if it has been renamed, as
391
# well as whatever files existed in revision 10 at path/foo
392
trees = [tree, work_tree]
397
if file_list is not None:
398
file_ids = bzrlib.tree.find_ids_across_trees(file_list, trees,
399
require_versioned=True)
400
# find_ids_across_trees may include some paths that don't
402
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
403
for file_id in file_ids if file_id in tree)
405
entries = tree.inventory.entries()
460
work_tree.lock_read()
462
if revision is not None:
463
if len(revision) > 1:
464
raise errors.BzrCommandError(
465
'bzr inventory --revision takes exactly one revision'
467
revision_id = revision[0].in_history(work_tree.branch).rev_id
468
tree = work_tree.branch.repository.revision_tree(revision_id)
470
extra_trees = [work_tree]
476
if file_list is not None:
477
file_ids = tree.paths2ids(file_list, trees=extra_trees,
478
require_versioned=True)
479
# find_ids_across_trees may include some paths that don't
481
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
482
for file_id in file_ids if file_id in tree)
484
entries = tree.inventory.entries()
487
if tree is not work_tree:
407
490
for path, entry in entries:
408
491
if kind and kind != entry.kind:
472
565
location can be accessed.
475
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
568
_see_also = ['push', 'update']
569
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
571
help='branch to pull into, '
572
'rather than the one containing the working directory',
476
577
takes_args = ['location?']
477
578
encoding_type = 'replace'
479
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
580
def run(self, location=None, remember=False, overwrite=False,
581
revision=None, verbose=False,
583
from bzrlib.tag import _merge_tags_if_possible
480
584
# FIXME: too much stuff is in the command class
587
if directory is None:
482
tree_to = WorkingTree.open_containing(u'.')[0]
590
tree_to = WorkingTree.open_containing(directory)[0]
483
591
branch_to = tree_to.branch
484
except NoWorkingTree:
592
except errors.NoWorkingTree:
486
branch_to = Branch.open_containing(u'.')[0]
594
branch_to = Branch.open_containing(directory)[0]
489
597
if location is not None:
491
reader = bundle.read_bundle_from_url(location)
599
mergeable = bundle.read_mergeable_from_url(
601
except errors.NotABundle:
493
602
pass # Continue on considering this url a Branch
495
604
stored_loc = branch_to.get_parent()
496
605
if location is None:
497
606
if stored_loc is None:
498
raise BzrCommandError("No pull location known or specified.")
607
raise errors.BzrCommandError("No pull location known or"
500
610
display_url = urlutils.unescape_for_display(stored_loc,
501
611
self.outf.encoding)
502
612
self.outf.write("Using saved location: %s\n" % display_url)
503
613
location = stored_loc
506
if reader is not None:
507
install_bundle(branch_to.repository, reader)
615
if mergeable is not None:
616
if revision is not None:
617
raise errors.BzrCommandError(
618
'Cannot use -r with merge directives or bundles')
619
revision_id = mergeable.install_revisions(branch_to.repository)
508
620
branch_from = branch_to
510
622
branch_from = Branch.open(location)
587
712
location = stored_loc
589
714
to_transport = transport.get_transport(location)
590
location_url = to_transport.base
716
br_to = repository_to = dir_to = None
718
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
719
except errors.NotBranchError:
720
pass # Didn't find anything
722
# If we can open a branch, use its direct repository, otherwise see
723
# if there is a repository without a branch.
725
br_to = dir_to.open_branch()
726
except errors.NotBranchError:
727
# Didn't find a branch, can we find a repository?
729
repository_to = dir_to.find_repository()
730
except errors.NoRepositoryPresent:
733
# Found a branch, so we must have found a repository
734
repository_to = br_to.repository
594
dir_to = bzrdir.BzrDir.open(location_url)
595
br_to = dir_to.open_branch()
596
except NotBranchError:
598
to_transport = to_transport.clone('..')
599
if not create_prefix:
601
relurl = to_transport.relpath(location_url)
602
mutter('creating directory %s => %s', location_url, relurl)
603
to_transport.mkdir(relurl)
605
raise BzrCommandError("Parent directory of %s "
606
"does not exist." % location)
608
current = to_transport.base
609
needed = [(to_transport, to_transport.relpath(location_url))]
612
to_transport, relpath = needed[-1]
613
to_transport.mkdir(relpath)
616
new_transport = to_transport.clone('..')
617
needed.append((new_transport,
618
new_transport.relpath(to_transport.base)))
619
if new_transport.base == to_transport.base:
620
raise BzrCommandError("Could not create "
622
dir_to = br_from.bzrdir.clone(location_url,
738
# The destination doesn't exist; create it.
739
# XXX: Refactor the create_prefix/no_create_prefix code into a
740
# common helper function
742
to_transport.mkdir('.')
743
except errors.FileExists:
744
if not use_existing_dir:
745
raise errors.BzrCommandError("Target directory %s"
746
" already exists, but does not have a valid .bzr"
747
" directory. Supply --use-existing-dir to push"
748
" there anyway." % location)
749
except errors.NoSuchFile:
750
if not create_prefix:
751
raise errors.BzrCommandError("Parent directory of %s"
753
"\nYou may supply --create-prefix to create all"
754
" leading parent directories."
757
_create_prefix(to_transport)
759
# Now the target directory exists, but doesn't have a .bzr
760
# directory. So we need to create it, along with any work to create
761
# all of the dependent branches, etc.
762
dir_to = br_from.bzrdir.clone_on_transport(to_transport,
623
763
revision_id=br_from.last_revision())
624
764
br_to = dir_to.open_branch()
625
count = len(br_to.revision_history())
765
# TODO: Some more useful message about what was copied
766
note('Created new branch.')
626
767
# We successfully created the target, remember it
627
768
if br_from.get_push_location() is None or remember:
628
769
br_from.set_push_location(br_to.base)
770
elif repository_to is None:
771
# we have a bzrdir but no branch or repository
772
# XXX: Figure out what to do other than complain.
773
raise errors.BzrCommandError("At %s you have a valid .bzr control"
774
" directory, but not a branch or repository. This is an"
775
" unsupported configuration. Please move the target directory"
776
" out of the way and try again."
779
# We have a repository but no branch, copy the revisions, and then
781
last_revision_id = br_from.last_revision()
782
repository_to.fetch(br_from.repository,
783
revision_id=last_revision_id)
784
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
785
note('Created new branch.')
786
if br_from.get_push_location() is None or remember:
787
br_from.set_push_location(br_to.base)
788
else: # We have a valid to branch
630
789
# We were able to connect to the remote location, so remember it
631
790
# we don't need to successfully push because of possible divergence.
632
791
if br_from.get_push_location() is None or remember:
905
1076
also new, they will also be removed.
907
1078
takes_args = ['file*']
908
takes_options = ['verbose', Option('new', help='remove newly-added files')]
1079
takes_options = ['verbose',
1080
Option('new', help='remove newly-added files'),
1081
RegistryOption.from_kwargs('file-deletion-strategy',
1082
'The file deletion mode to be used',
1083
title='Deletion Strategy', value_switches=True, enum_switch=False,
1084
safe='Only delete files if they can be'
1085
' safely recovered (default).',
1086
keep="Don't delete any files.",
1087
force='Delete all the specified files, even if they can not be '
1088
'recovered and even if they are non-empty directories.')]
909
1089
aliases = ['rm']
910
1090
encoding_type = 'replace'
912
def run(self, file_list, verbose=False, new=False):
1092
def run(self, file_list, verbose=False, new=False,
1093
file_deletion_strategy='safe'):
913
1094
tree, file_list = tree_files(file_list)
915
if file_list is None:
916
raise BzrCommandError('Specify one or more files to remove, or'
1096
if file_list is not None:
1097
file_list = [f for f in file_list if f != '']
1099
raise errors.BzrCommandError('Specify one or more files to'
1100
' remove, or use --new.')
919
1103
added = tree.changes_from(tree.basis_tree(),
920
1104
specific_files=file_list).added
921
1105
file_list = sorted([f[0] for f in added], reverse=True)
922
1106
if len(file_list) == 0:
923
raise BzrCommandError('No matching files.')
924
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1107
raise errors.BzrCommandError('No matching files.')
1108
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1109
keep_files=file_deletion_strategy=='keep',
1110
force=file_deletion_strategy=='force')
927
1113
class cmd_file_id(Command):
1073
1278
# Just using os.mkdir, since I don't
1074
1279
# believe that we want to create a bunch of
1075
1280
# locations if the user supplies an extended path
1076
# TODO: create-prefix
1078
to_transport.mkdir('.')
1079
except errors.FileExists:
1282
to_transport.ensure_base()
1283
except errors.NoSuchFile:
1284
if not create_prefix:
1285
raise errors.BzrCommandError("Parent directory of %s"
1287
"\nYou may supply --create-prefix to create all"
1288
" leading parent directories."
1290
_create_prefix(to_transport)
1083
1293
existing_bzrdir = bzrdir.BzrDir.open(location)
1084
except NotBranchError:
1294
except errors.NotBranchError:
1085
1295
# really a NotBzrDir error...
1086
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1296
branch = bzrdir.BzrDir.create_branch_convenience(to_transport.base,
1299
from bzrlib.transport.local import LocalTransport
1088
1300
if existing_bzrdir.has_branch():
1089
1301
if (isinstance(to_transport, LocalTransport)
1090
1302
and not existing_bzrdir.has_workingtree()):
1091
1303
raise errors.BranchExistsWithoutWorkingTree(location)
1092
1304
raise errors.AlreadyBranchError(location)
1094
existing_bzrdir.create_branch()
1306
branch = existing_bzrdir.create_branch()
1095
1307
existing_bzrdir.create_workingtree()
1308
if append_revisions_only:
1310
branch.set_append_revisions_only(True)
1311
except errors.UpgradeRequired:
1312
raise errors.BzrCommandError('This branch format cannot be set'
1313
' to append-revisions-only. Try --experimental-branch6')
1098
1316
class cmd_init_repository(Command):
1099
1317
"""Create a shared repository to hold branches.
1101
New branches created under the repository directory will store their revisions
1102
in the repository, not in the branch directory, if the branch format supports
1319
New branches created under the repository directory will store their
1320
revisions in the repository, not in the branch directory.
1322
If the --no-trees option is used then the branches in the repository
1323
will not have working trees by default.
1326
bzr init-repo --no-trees repo
1107
1327
bzr init repo/trunk
1108
1328
bzr checkout --lightweight repo/trunk trunk-checkout
1109
1329
cd trunk-checkout
1110
1330
(add files here)
1332
See 'bzr help repositories' for more information.
1112
takes_args = ["location"]
1113
takes_options = [Option('format',
1114
help='Specify a format for this repository.'
1115
' Current formats are: default, knit,'
1116
' metaweave and weave. Default is knit;'
1117
' metaweave and weave are deprecated',
1118
type=get_format_type),
1120
help='Allows branches in repository to have'
1335
_see_also = ['init', 'branch', 'checkout']
1336
takes_args = ["location"]
1337
takes_options = [RegistryOption('format',
1338
help='Specify a format for this repository. See'
1339
' "bzr help formats" for details',
1340
registry=bzrdir.format_registry,
1341
converter=bzrdir.format_registry.make_bzrdir,
1342
value_switches=True, title='Repository format'),
1344
help='Branches in the repository will default to'
1345
' not having a working tree'),
1122
1347
aliases = ["init-repo"]
1123
def run(self, location, format=None, trees=False):
1349
def run(self, location, format=None, no_trees=False):
1124
1350
if format is None:
1125
format = get_format_type('default')
1351
format = bzrdir.format_registry.make_bzrdir('default')
1127
1353
if location is None:
1130
1356
to_transport = transport.get_transport(location)
1132
to_transport.mkdir('.')
1133
except errors.FileExists:
1357
to_transport.ensure_base()
1136
1359
newdir = format.initialize_on_transport(to_transport)
1137
1360
repo = newdir.create_repository(shared=True)
1138
repo.set_make_working_trees(trees)
1361
repo.set_make_working_trees(not no_trees)
1141
1364
class cmd_diff(Command):
1218
1453
tree1, tree2 = None, None
1221
if revision is not None:
1222
if tree2 is not None:
1223
raise BzrCommandError("Can't specify -r with two branches")
1224
if (len(revision) == 1) or (revision[1].spec is None):
1225
return diff_cmd_helper(tree1, file_list, diff_options,
1227
old_label=old_label, new_label=new_label)
1228
elif len(revision) == 2:
1229
return diff_cmd_helper(tree1, file_list, diff_options,
1230
revision[0], revision[1],
1231
old_label=old_label, new_label=new_label)
1233
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1235
if tree2 is not None:
1236
return show_diff_trees(tree1, tree2, sys.stdout,
1237
specific_files=file_list,
1238
external_diff_options=diff_options,
1239
old_label=old_label, new_label=new_label)
1241
return diff_cmd_helper(tree1, file_list, diff_options,
1242
old_label=old_label, new_label=new_label)
1457
if tree2 is not None:
1458
if revision is not None:
1459
# FIXME: but there should be a clean way to diff between
1460
# non-default versions of two trees, it's not hard to do
1462
raise errors.BzrCommandError(
1463
"Sorry, diffing arbitrary revisions across branches "
1464
"is not implemented yet")
1465
return show_diff_trees(tree1, tree2, sys.stdout,
1466
specific_files=file_list,
1467
external_diff_options=diff_options,
1468
old_label=old_label, new_label=new_label)
1470
return diff_cmd_helper(tree1, file_list, diff_options,
1471
revision_specs=revision,
1472
old_label=old_label, new_label=new_label)
1245
1475
class cmd_deleted(Command):
1382
1650
dir, relpath = bzrdir.BzrDir.open_containing(location)
1383
1651
b = dir.open_branch()
1385
if revision is None:
1388
elif len(revision) == 1:
1389
rev1 = rev2 = revision[0].in_history(b).revno
1390
elif len(revision) == 2:
1391
if revision[1].get_branch() != revision[0].get_branch():
1392
# b is taken from revision[0].get_branch(), and
1393
# show_log will use its revision_history. Having
1394
# different branches will lead to weird behaviors.
1395
raise BzrCommandError(
1396
"Log doesn't accept two revisions in different branches.")
1397
if revision[0].spec is None:
1398
# missing begin-range means first revision
1401
rev1 = revision[0].in_history(b).revno
1403
if revision[1].spec is None:
1404
# missing end-range means last known revision
1407
rev2 = revision[1].in_history(b).revno
1409
raise BzrCommandError('bzr log --revision takes one or two values.')
1411
# By this point, the revision numbers are converted to the +ve
1412
# form if they were supplied in the -ve form, so we can do
1413
# this comparison in relative safety
1415
(rev2, rev1) = (rev1, rev2)
1417
if (log_format is None):
1418
default = b.get_config().log_format()
1419
log_format = get_log_format(long=long, short=short, line=line,
1421
lf = log_formatter(log_format,
1424
show_timezone=timezone)
1430
direction=direction,
1431
start_revision=rev1,
1655
if revision is None:
1658
elif len(revision) == 1:
1659
rev1 = rev2 = revision[0].in_history(b).revno
1660
elif len(revision) == 2:
1661
if revision[1].get_branch() != revision[0].get_branch():
1662
# b is taken from revision[0].get_branch(), and
1663
# show_log will use its revision_history. Having
1664
# different branches will lead to weird behaviors.
1665
raise errors.BzrCommandError(
1666
"Log doesn't accept two revisions in different"
1668
if revision[0].spec is None:
1669
# missing begin-range means first revision
1672
rev1 = revision[0].in_history(b).revno
1674
if revision[1].spec is None:
1675
# missing end-range means last known revision
1678
rev2 = revision[1].in_history(b).revno
1680
raise errors.BzrCommandError(
1681
'bzr log --revision takes one or two values.')
1683
# By this point, the revision numbers are converted to the +ve
1684
# form if they were supplied in the -ve form, so we can do
1685
# this comparison in relative safety
1687
(rev2, rev1) = (rev1, rev2)
1689
if log_format is None:
1690
log_format = log.log_formatter_registry.get_default(b)
1692
lf = log_format(show_ids=show_ids, to_file=self.outf,
1693
show_timezone=timezone)
1699
direction=direction,
1700
start_revision=rev1,
1436
1708
def get_log_format(long=False, short=False, line=False, default='long'):
1478
1751
Option('ignored', help='Print ignored files'),
1480
1753
Option('null', help='Null separate the files'),
1482
1756
@display_command
1483
1757
def run(self, revision=None, verbose=False,
1484
1758
non_recursive=False, from_root=False,
1485
1759
unknown=False, versioned=False, ignored=False,
1760
null=False, kind=None, show_ids=False, path=None):
1762
if kind and kind not in ('file', 'directory', 'symlink'):
1763
raise errors.BzrCommandError('invalid kind specified')
1488
1765
if verbose and null:
1489
raise BzrCommandError('Cannot set both --verbose and --null')
1766
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1490
1767
all = not (unknown or versioned or ignored)
1492
1769
selection = {'I':ignored, '?':unknown, 'V':versioned}
1494
tree, relpath = WorkingTree.open_containing(u'.')
1776
raise errors.BzrCommandError('cannot specify both --from-root'
1780
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1499
1786
if revision is not None:
1500
tree = tree.branch.repository.revision_tree(
1501
revision[0].in_history(tree.branch).rev_id)
1787
tree = branch.repository.revision_tree(
1788
revision[0].in_history(branch).rev_id)
1790
tree = branch.basis_tree()
1503
for fp, fc, kind, fid, entry in tree.list_files():
1504
if fp.startswith(relpath):
1505
fp = fp[len(relpath):]
1506
if non_recursive and '/' in fp:
1508
if not all and not selection[fc]:
1511
kindch = entry.kind_character()
1512
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1514
self.outf.write(fp + '\0')
1517
self.outf.write(fp + '\n')
1794
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1795
if fp.startswith(relpath):
1796
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1797
if non_recursive and '/' in fp:
1799
if not all and not selection[fc]:
1801
if kind is not None and fkind != kind:
1804
kindch = entry.kind_character()
1805
outstring = '%-8s %s%s' % (fc, fp, kindch)
1806
if show_ids and fid is not None:
1807
outstring = "%-50s %s" % (outstring, fid)
1808
self.outf.write(outstring + '\n')
1810
self.outf.write(fp + '\0')
1813
self.outf.write(fid)
1814
self.outf.write('\0')
1822
self.outf.write('%-50s %s\n' % (fp, my_id))
1824
self.outf.write(fp + '\n')
1520
1829
class cmd_unknowns(Command):
1521
"""List unknown files."""
1830
"""List unknown files.
1522
1836
@display_command
1524
1838
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1528
1842
class cmd_ignore(Command):
1529
"""Ignore a command or pattern.
1843
"""Ignore specified files or patterns.
1531
1845
To remove patterns from the ignore list, edit the .bzrignore file.
1533
If the pattern contains a slash, it is compared to the whole path
1534
from the branch root. Otherwise, it is compared to only the last
1535
component of the path. To match a file only in the root directory,
1538
Ignore patterns are case-insensitive on case-insensitive systems.
1540
Note: wildcards must be quoted from the shell on Unix.
1847
Trailing slashes on patterns are ignored.
1848
If the pattern contains a slash or is a regular expression, it is compared
1849
to the whole path from the branch root. Otherwise, it is compared to only
1850
the last component of the path. To match a file only in the root
1851
directory, prepend './'.
1853
Ignore patterns specifying absolute paths are not allowed.
1855
Ignore patterns may include globbing wildcards such as:
1856
? - Matches any single character except '/'
1857
* - Matches 0 or more characters except '/'
1858
/**/ - Matches 0 or more directories in a path
1859
[a-z] - Matches a single character from within a group of characters
1861
Ignore patterns may also be Python regular expressions.
1862
Regular expression ignore patterns are identified by a 'RE:' prefix
1863
followed by the regular expression. Regular expression ignore patterns
1864
may not include named or numbered groups.
1866
Note: ignore patterns containing shell wildcards must be quoted from
1543
1870
bzr ignore ./Makefile
1544
1871
bzr ignore '*.class'
1872
bzr ignore 'lib/**/*.o'
1873
bzr ignore 'RE:lib/.*\.o'
1546
# TODO: Complain if the filename is absolute
1547
takes_args = ['name_pattern?']
1876
_see_also = ['status', 'ignored']
1877
takes_args = ['name_pattern*']
1548
1878
takes_options = [
1549
1879
Option('old-default-rules',
1550
1880
help='Out the ignore rules bzr < 0.9 always used.')
1553
def run(self, name_pattern=None, old_default_rules=None):
1883
def run(self, name_pattern_list=None, old_default_rules=None):
1554
1884
from bzrlib.atomicfile import AtomicFile
1555
1885
if old_default_rules is not None:
1556
1886
# dump the rules and exit
1557
1887
for pattern in ignores.OLD_DEFAULTS:
1560
if name_pattern is None:
1561
raise BzrCommandError("ignore requires a NAME_PATTERN")
1890
if not name_pattern_list:
1891
raise errors.BzrCommandError("ignore requires at least one "
1892
"NAME_PATTERN or --old-default-rules")
1893
name_pattern_list = [globbing.normalize_pattern(p)
1894
for p in name_pattern_list]
1895
for name_pattern in name_pattern_list:
1896
if (name_pattern[0] == '/' or
1897
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1898
raise errors.BzrCommandError(
1899
"NAME_PATTERN should not be an absolute path")
1562
1900
tree, relpath = WorkingTree.open_containing(u'.')
1563
1901
ifn = tree.abspath('.bzrignore')
1564
1902
if os.path.exists(ifn):
1648
1992
tgz .tar.gz, .tgz
1651
takes_args = ['dest']
1995
takes_args = ['dest', 'branch?']
1652
1996
takes_options = ['revision', 'format', 'root']
1653
def run(self, dest, revision=None, format=None, root=None):
1997
def run(self, dest, branch=None, revision=None, format=None, root=None):
1654
1998
from bzrlib.export import export
1655
tree = WorkingTree.open_containing(u'.')[0]
2001
tree = WorkingTree.open_containing(u'.')[0]
2004
b = Branch.open(branch)
1657
2006
if revision is None:
1658
2007
# should be tree.last_revision FIXME
1659
2008
rev_id = b.last_revision()
1661
2010
if len(revision) != 1:
1662
raise BzrError('bzr export --revision takes exactly 1 argument')
2011
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1663
2012
rev_id = revision[0].in_history(b).rev_id
1664
2013
t = b.repository.revision_tree(rev_id)
1666
2015
export(t, dest, format, root)
1667
2016
except errors.NoSuchExportFormat, e:
1668
raise BzrCommandError('Unsupported export format: %s' % e.format)
2017
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1671
2020
class cmd_cat(Command):
1672
"""Write a file's text from a previous revision."""
1674
takes_options = ['revision']
2021
"""Write the contents of a file as of a given revision to standard output.
2023
If no revision is nominated, the last revision is used.
2025
Note: Take care to redirect standard output when using this command on a
2030
takes_options = ['revision', 'name-from-revision']
1675
2031
takes_args = ['filename']
2032
encoding_type = 'exact'
1677
2034
@display_command
1678
def run(self, filename, revision=None):
2035
def run(self, filename, revision=None, name_from_revision=False):
1679
2036
if revision is not None and len(revision) != 1:
1680
raise BzrCommandError("bzr cat --revision takes exactly one number")
2037
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1683
tree, relpath = WorkingTree.open_containing(filename)
1685
except NotBranchError:
2042
tree, b, relpath = \
2043
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2044
except errors.NotBranchError:
1689
b, relpath = Branch.open_containing(filename)
1690
2047
if revision is not None and revision[0].get_branch() is not None:
1691
2048
b = Branch.open(revision[0].get_branch())
2050
tree = b.basis_tree()
1692
2051
if revision is None:
1693
2052
revision_id = b.last_revision()
1695
2054
revision_id = revision[0].in_history(b).rev_id
1696
b.print_file(relpath, revision_id)
2056
cur_file_id = tree.path2id(relpath)
2057
rev_tree = b.repository.revision_tree(revision_id)
2058
old_file_id = rev_tree.path2id(relpath)
2060
if name_from_revision:
2061
if old_file_id is None:
2062
raise errors.BzrCommandError("%r is not present in revision %s"
2063
% (filename, revision_id))
2065
rev_tree.print_file(old_file_id)
2066
elif cur_file_id is not None:
2067
rev_tree.print_file(cur_file_id)
2068
elif old_file_id is not None:
2069
rev_tree.print_file(old_file_id)
2071
raise errors.BzrCommandError("%r is not present in revision %s" %
2072
(filename, revision_id))
1699
2075
class cmd_local_time_offset(Command):
1747
2143
aliases = ['ci', 'checkin']
2145
def _get_bug_fix_properties(self, fixes, branch):
2147
# Configure the properties for bug fixing attributes.
2148
for fixed_bug in fixes:
2149
tokens = fixed_bug.split(':')
2150
if len(tokens) != 2:
2151
raise errors.BzrCommandError(
2152
"Invalid bug %s. Must be in the form of 'tag:id'. "
2153
"Commit refused." % fixed_bug)
2154
tag, bug_id = tokens
2156
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2157
except errors.UnknownBugTrackerAbbreviation:
2158
raise errors.BzrCommandError(
2159
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2160
except errors.MalformedBugIdentifier:
2161
raise errors.BzrCommandError(
2162
"Invalid bug identifier for %s. Commit refused."
2164
properties.append('%s fixed' % bug_url)
2165
return '\n'.join(properties)
1749
2167
def run(self, message=None, file=None, verbose=True, selected_list=None,
1750
unchanged=False, strict=False, local=False):
2168
unchanged=False, strict=False, local=False, fixes=None):
1751
2169
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
1752
2170
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1753
2171
StrictCommitFailed)
1754
2172
from bzrlib.msgeditor import edit_commit_message, \
1755
2173
make_commit_message_template
1756
from tempfile import TemporaryFile
1758
2175
# TODO: Need a blackbox test for invoking the external editor; may be
1759
2176
# slightly problematic to run this cross-platform.
1761
2178
# TODO: do more checks that the commit will succeed before
1762
2179
# spending the user's valuable time typing a commit message.
1764
# TODO: if the commit *does* happen to fail, then save the commit
1765
# message to a temporary file where it can be recovered
1766
2183
tree, selected_list = tree_files(selected_list)
1767
2184
if selected_list == ['']:
1768
2185
# workaround - commit of root of tree should be exactly the same
1770
2187
# selected-file merge commit is not done yet
1771
2188
selected_list = []
2190
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2192
properties['bugs'] = bug_property
1773
2194
if local and not tree.branch.get_bound_location():
1774
2195
raise errors.LocalRequiresBoundBranch()
1775
if message is None and not file:
1776
template = make_commit_message_template(tree, selected_list)
1777
message = edit_commit_message(template)
1779
raise BzrCommandError("please specify a commit message"
1780
" with either --message or --file")
1781
elif message and file:
1782
raise BzrCommandError("please specify either --message or --file")
1785
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1788
raise BzrCommandError("empty commit message specified")
2197
def get_message(commit_obj):
2198
"""Callback to get commit message"""
2199
my_message = message
2200
if my_message is None and not file:
2201
template = make_commit_message_template(tree, selected_list)
2202
my_message = edit_commit_message(template)
2203
if my_message is None:
2204
raise errors.BzrCommandError("please specify a commit"
2205
" message with either --message or --file")
2206
elif my_message and file:
2207
raise errors.BzrCommandError(
2208
"please specify either --message or --file")
2210
my_message = codecs.open(file, 'rt',
2211
bzrlib.user_encoding).read()
2212
if my_message == "":
2213
raise errors.BzrCommandError("empty commit message specified")
1791
2217
reporter = ReportCommitToLog()
1793
2219
reporter = NullCommitReporter()
1796
tree.commit(message, specific_files=selected_list,
2222
tree.commit(message_callback=get_message,
2223
specific_files=selected_list,
1797
2224
allow_pointless=unchanged, strict=strict, local=local,
2225
reporter=reporter, revprops=properties)
1799
2226
except PointlessCommit:
1800
2227
# FIXME: This should really happen before the file is read in;
1801
2228
# perhaps prepare the commit; get the message; then actually commit
1802
raise BzrCommandError("no changes to commit."
1803
" use --unchanged to commit anyhow")
2229
raise errors.BzrCommandError("no changes to commit."
2230
" use --unchanged to commit anyhow")
1804
2231
except ConflictsInTree:
1805
raise BzrCommandError("Conflicts detected in working tree. "
1806
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
2232
raise errors.BzrCommandError('Conflicts detected in working '
2233
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1807
2235
except StrictCommitFailed:
1808
raise BzrCommandError("Commit refused because there are unknown "
1809
"files in the working tree.")
2236
raise errors.BzrCommandError("Commit refused because there are"
2237
" unknown files in the working tree.")
1810
2238
except errors.BoundBranchOutOfDate, e:
1811
raise BzrCommandError(str(e) + "\n"
1812
'To commit to master branch, run update and then commit.\n'
1813
'You can also pass --local to commit to continue working '
2239
raise errors.BzrCommandError(str(e) + "\n"
2240
'To commit to master branch, run update and then commit.\n'
2241
'You can also pass --local to commit to continue working '
1816
2245
class cmd_check(Command):
1817
2246
"""Validate consistency of branch history.
1938
2353
@display_command
1939
2354
def printme(self, branch):
1943
2358
class cmd_selftest(Command):
1944
2359
"""Run internal test suite.
1946
This creates temporary test directories in the working directory,
1947
but not existing data is affected. These directories are deleted
1948
if the tests pass, or left behind to help in debugging if they
1949
fail and --keep-output is specified.
1951
If arguments are given, they are regular expressions that say
1952
which tests should run.
2361
If arguments are given, they are regular expressions that say which tests
2362
should run. Tests matching any expression are run, and other tests are
2365
Alternatively if --first is given, matching tests are run first and then
2366
all other tests are run. This is useful if you have been working in a
2367
particular area, but want to make sure nothing else was broken.
2369
If --exclude is given, tests that match that regular expression are
2370
excluded, regardless of whether they match --first or not.
2372
To help catch accidential dependencies between tests, the --randomize
2373
option is useful. In most cases, the argument used is the word 'now'.
2374
Note that the seed used for the random number generator is displayed
2375
when this option is used. The seed can be explicitly passed as the
2376
argument to this option if required. This enables reproduction of the
2377
actual ordering used if and when an order sensitive problem is encountered.
2379
If --list-only is given, the tests that would be run are listed. This is
2380
useful when combined with --first, --exclude and/or --randomize to
2381
understand their impact. The test harness reports "Listed nn tests in ..."
2382
instead of "Ran nn tests in ..." when list mode is enabled.
1954
2384
If the global option '--no-plugins' is given, plugins are not loaded
1955
2385
before running the selftests. This has two effects: features provided or
1956
2386
modified by plugins will not be tested, and tests provided by plugins will
1960
2390
bzr selftest ignore
2391
run only tests relating to 'ignore'
1961
2392
bzr --no-plugins selftest -v
2393
disable plugins and list tests as they're run
2395
For each test, that needs actual disk access, bzr create their own
2396
subdirectory in the temporary testing directory (testXXXX.tmp).
2397
By default the name of such subdirectory is based on the name of the test.
2398
If option '--numbered-dirs' is given, bzr will use sequent numbers
2399
of running tests to create such subdirectories. This is default behavior
2400
on Windows because of path length limitation.
1963
# TODO: --list should give a list of all available tests
1965
2402
# NB: this is used from the class without creating an instance, which is
1966
2403
# why it does not have a self parameter.
1967
2404
def get_transport_type(typestring):
1977
2414
return FakeNFSServer
1978
2415
msg = "No known transport type %s. Supported types are: sftp\n" %\
1980
raise BzrCommandError(msg)
2417
raise errors.BzrCommandError(msg)
1983
2420
takes_args = ['testspecs*']
1984
2421
takes_options = ['verbose',
1985
Option('one', help='stop when one test fails'),
1986
Option('keep-output',
2423
help='stop when one test fails',
2426
Option('keep-output',
1987
2427
help='keep output directories when tests fail'),
1989
2429
help='Use a different transport by default '
1990
2430
'throughout the test suite.',
1991
2431
type=get_transport_type),
1992
Option('benchmark', help='run the bzr bencharks.'),
2432
Option('benchmark', help='run the bzr benchmarks.'),
1993
2433
Option('lsprof-timed',
1994
2434
help='generate lsprof output for benchmarked'
1995
2435
' sections of code.'),
1996
2436
Option('cache-dir', type=str,
1997
2437
help='a directory to cache intermediate'
1998
2438
' benchmark steps'),
2439
Option('clean-output',
2440
help='clean temporary tests directories'
2441
' without running tests'),
2443
help='run all tests, but run specified tests first',
2446
Option('numbered-dirs',
2447
help='use numbered dirs for TestCaseInTempDir'),
2449
help='list the tests instead of running them'),
2450
Option('randomize', type=str, argname="SEED",
2451
help='randomize the order of tests using the given'
2452
' seed or "now" for the current time'),
2453
Option('exclude', type=str, argname="PATTERN",
2455
help='exclude tests that match this regular'
2458
encoding_type = 'replace'
2001
2460
def run(self, testspecs_list=None, verbose=None, one=False,
2002
2461
keep_output=False, transport=None, benchmark=None,
2003
lsprof_timed=None, cache_dir=None):
2462
lsprof_timed=None, cache_dir=None, clean_output=False,
2463
first=False, numbered_dirs=None, list_only=False,
2464
randomize=None, exclude=None):
2004
2465
import bzrlib.ui
2005
2466
from bzrlib.tests import selftest
2006
2467
import bzrlib.benchmarks as benchmarks
2007
2468
from bzrlib.benchmarks import tree_creator
2471
from bzrlib.tests import clean_selftest_output
2472
clean_selftest_output()
2475
warning("notice: selftest --keep-output "
2476
"is no longer supported; "
2477
"test output is always removed")
2479
if numbered_dirs is None and sys.platform == 'win32':
2480
numbered_dirs = True
2009
2482
if cache_dir is not None:
2010
2483
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2011
# we don't want progress meters from the tests to go to the
2012
# real output; and we don't want log messages cluttering up
2014
save_ui = ui.ui_factory
2015
2484
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2016
2485
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2018
info('running tests...')
2487
if testspecs_list is not None:
2488
pattern = '|'.join(testspecs_list)
2492
test_suite_factory = benchmarks.test_suite
2495
# TODO: should possibly lock the history file...
2496
benchfile = open(".perf_history", "at", buffering=1)
2498
test_suite_factory = None
2020
ui.ui_factory = ui.SilentUIFactory()
2021
if testspecs_list is not None:
2022
pattern = '|'.join(testspecs_list)
2026
test_suite_factory = benchmarks.test_suite
2029
# TODO: should possibly lock the history file...
2030
benchfile = open(".perf_history", "at")
2032
test_suite_factory = None
2037
result = selftest(verbose=verbose,
2039
stop_on_failure=one,
2040
keep_output=keep_output,
2041
transport=transport,
2042
test_suite_factory=test_suite_factory,
2043
lsprof_timed=lsprof_timed,
2044
bench_history=benchfile)
2046
if benchfile is not None:
2049
info('tests passed')
2051
info('tests failed')
2052
return int(not result)
2503
result = selftest(verbose=verbose,
2505
stop_on_failure=one,
2506
transport=transport,
2507
test_suite_factory=test_suite_factory,
2508
lsprof_timed=lsprof_timed,
2509
bench_history=benchfile,
2510
matching_tests_first=first,
2511
numbered_dirs=numbered_dirs,
2512
list_only=list_only,
2513
random_seed=randomize,
2514
exclude_pattern=exclude
2054
ui.ui_factory = save_ui
2517
if benchfile is not None:
2520
info('tests passed')
2522
info('tests failed')
2523
return int(not result)
2057
2526
class cmd_version(Command):
2126
2590
default, use --remember. The value will only be saved if the remote
2127
2591
location can be accessed.
2593
The results of the merge are placed into the destination working
2594
directory, where they can be reviewed (with bzr diff), tested, and then
2595
committed to record the result of the merge.
2131
To merge the latest revision from bzr.dev
2132
bzr merge ../bzr.dev
2599
To merge the latest revision from bzr.dev:
2600
bzr merge ../bzr.dev
2134
To merge changes up to and including revision 82 from bzr.dev
2135
bzr merge -r 82 ../bzr.dev
2602
To merge changes up to and including revision 82 from bzr.dev:
2603
bzr merge -r 82 ../bzr.dev
2137
2605
To merge the changes introduced by 82, without previous changes:
2138
bzr merge -r 81..82 ../bzr.dev
2606
bzr merge -r 81..82 ../bzr.dev
2140
2608
merge refuses to run if there are any uncommitted changes, unless
2141
2609
--force is given.
2143
The following merge types are available:
2612
_see_also = ['update', 'remerge']
2145
2613
takes_args = ['branch?']
2146
2614
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2147
Option('show-base', help="Show base revision text in "
2149
Option('uncommitted', help='Apply uncommitted changes'
2150
' from a working copy, instead of branch changes')]
2153
from merge import merge_type_help
2154
from inspect import getdoc
2155
return getdoc(self) + '\n' + merge_type_help()
2615
Option('show-base', help="Show base revision text in "
2617
Option('uncommitted', help='Apply uncommitted changes'
2618
' from a working copy, instead of branch changes'),
2619
Option('pull', help='If the destination is already'
2620
' completely merged into the source, pull from the'
2621
' source rather than merging. When this happens,'
2622
' you do not need to commit the result.'),
2624
help='Branch to merge into, '
2625
'rather than the one containing the working directory',
2157
2631
def run(self, branch=None, revision=None, force=False, merge_type=None,
2158
show_base=False, reprocess=False, remember=False,
2632
show_base=False, reprocess=False, remember=False,
2633
uncommitted=False, pull=False,
2636
from bzrlib.tag import _merge_tags_if_possible
2637
other_revision_id = None
2160
2638
if merge_type is None:
2161
merge_type = Merge3Merger
2639
merge_type = _mod_merge.Merge3Merger
2163
tree = WorkingTree.open_containing(u'.')[0]
2641
if directory is None: directory = u'.'
2642
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2643
# inventory. Because merge is a mutating operation, it really
2644
# should be a lock_write() for the whole cmd_merge operation.
2645
# However, cmd_merge open's its own tree in _merge_helper, which
2646
# means if we lock here, the later lock_write() will always block.
2647
# Either the merge helper code should be updated to take a tree,
2648
# (What about tree.merge_from_branch?)
2649
tree = WorkingTree.open_containing(directory)[0]
2650
change_reporter = delta._ChangeReporter(
2651
unversioned_filter=tree.is_ignored)
2165
2653
if branch is not None:
2167
reader = bundle.read_bundle_from_url(branch)
2655
mergeable = bundle.read_mergeable_from_url(
2657
except errors.NotABundle:
2169
2658
pass # Continue on considering this url a Branch
2171
conflicts = merge_bundle(reader, tree, not force, merge_type,
2172
reprocess, show_base)
2660
if revision is not None:
2661
raise errors.BzrCommandError(
2662
'Cannot use -r with merge directives or bundles')
2663
other_revision_id = mergeable.install_revisions(
2664
tree.branch.repository)
2665
revision = [RevisionSpec.from_string(
2666
'revid:' + other_revision_id)]
2178
2668
if revision is None \
2179
2669
or len(revision) < 1 or revision[0].needs_branch():
2657
3184
if to_revid is None:
2658
3185
to_revno = b.revno()
2659
3186
if from_revno is None or to_revno is None:
2660
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
3187
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2661
3188
for revno in range(from_revno, to_revno + 1):
2662
3189
b.repository.sign_revision(b.get_rev_id(revno),
2665
raise BzrCommandError('Please supply either one revision, or a range.')
3192
raise errors.BzrCommandError('Please supply either one revision, or a range.')
2668
3195
class cmd_bind(Command):
2669
"""Bind the current branch to a master branch.
3196
"""Convert the current branch into a checkout of the supplied branch.
2671
After binding, commits must succeed on the master branch
2672
before they are executed on the local one.
3198
Once converted into a checkout, commits must succeed on the master branch
3199
before they will be applied to the local branch.
2675
takes_args = ['location']
3202
_see_also = ['checkouts', 'unbind']
3203
takes_args = ['location?']
2676
3204
takes_options = []
2678
3206
def run(self, location=None):
2679
3207
b, relpath = Branch.open_containing(u'.')
3208
if location is None:
3210
location = b.get_old_bound_location()
3211
except errors.UpgradeRequired:
3212
raise errors.BzrCommandError('No location supplied. '
3213
'This format does not remember old locations.')
3215
if location is None:
3216
raise errors.BzrCommandError('No location supplied and no '
3217
'previous location known')
2680
3218
b_other = Branch.open(location)
2682
3220
b.bind(b_other)
2683
except DivergedBranches:
2684
raise BzrCommandError('These branches have diverged.'
2685
' Try merging, and then bind again.')
3221
except errors.DivergedBranches:
3222
raise errors.BzrCommandError('These branches have diverged.'
3223
' Try merging, and then bind again.')
2688
3226
class cmd_unbind(Command):
2689
"""Unbind the current branch from its master branch.
3227
"""Convert the current checkout into a regular branch.
2691
After unbinding, the local branch is considered independent.
2692
All subsequent commits will be local.
3229
After unbinding, the local branch is considered independent and subsequent
3230
commits will be local only.
3233
_see_also = ['checkouts', 'bind']
2695
3234
takes_args = []
2696
3235
takes_options = []
2699
3238
b, relpath = Branch.open_containing(u'.')
2700
3239
if not b.unbind():
2701
raise BzrCommandError('Local branch is not bound')
3240
raise errors.BzrCommandError('Local branch is not bound')
2704
3243
class cmd_uncommit(Command):
2846
3387
def run(self, port=None, inet=False, directory=None, allow_writes=False):
2847
from bzrlib.transport import smart
3388
from bzrlib.smart import medium, server
2848
3389
from bzrlib.transport import get_transport
3390
from bzrlib.transport.chroot import ChrootServer
3391
from bzrlib.transport.remote import BZR_DEFAULT_PORT, BZR_DEFAULT_INTERFACE
2849
3392
if directory is None:
2850
3393
directory = os.getcwd()
2851
3394
url = urlutils.local_path_to_url(directory)
2852
3395
if not allow_writes:
2853
3396
url = 'readonly+' + url
2854
t = get_transport(url)
3397
chroot_server = ChrootServer(get_transport(url))
3398
chroot_server.setUp()
3399
t = get_transport(chroot_server.get_url())
2856
server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
2857
elif port is not None:
2859
host, port = port.split(':')
3401
smart_server = medium.SmartServerPipeStreamMedium(
3402
sys.stdin, sys.stdout, t)
3404
host = BZR_DEFAULT_INTERFACE
3406
port = BZR_DEFAULT_PORT
2862
server = smart.SmartTCPServer(t, host=host, port=int(port))
2863
print 'listening on port: ', server.port
3409
host, port = port.split(':')
3411
smart_server = server.SmartTCPServer(t, host=host, port=port)
3412
print 'listening on port: ', smart_server.port
2864
3413
sys.stdout.flush()
2866
raise BzrCommandError("bzr serve requires one of --inet or --port")
3414
# for the duration of this server, no UI output is permitted.
3415
# note that this may cause problems with blackbox tests. This should
3416
# be changed with care though, as we dont want to use bandwidth sending
3417
# progress over stderr to smart server clients!
3418
old_factory = ui.ui_factory
3420
ui.ui_factory = ui.SilentUIFactory()
3421
smart_server.serve()
3423
ui.ui_factory = old_factory
3426
class cmd_join(Command):
3427
"""Combine a subtree into its containing tree.
3429
This command is for experimental use only. It requires the target tree
3430
to be in dirstate-with-subtree format, which cannot be converted into
3433
The TREE argument should be an independent tree, inside another tree, but
3434
not part of it. (Such trees can be produced by "bzr split", but also by
3435
running "bzr branch" with the target inside a tree.)
3437
The result is a combined tree, with the subtree no longer an independant
3438
part. This is marked as a merge of the subtree into the containing tree,
3439
and all history is preserved.
3441
If --reference is specified, the subtree retains its independence. It can
3442
be branched by itself, and can be part of multiple projects at the same
3443
time. But operations performed in the containing tree, such as commit
3444
and merge, will recurse into the subtree.
3447
_see_also = ['split']
3448
takes_args = ['tree']
3449
takes_options = [Option('reference', 'join by reference')]
3452
def run(self, tree, reference=False):
3453
sub_tree = WorkingTree.open(tree)
3454
parent_dir = osutils.dirname(sub_tree.basedir)
3455
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3456
repo = containing_tree.branch.repository
3457
if not repo.supports_rich_root():
3458
raise errors.BzrCommandError(
3459
"Can't join trees because %s doesn't support rich root data.\n"
3460
"You can use bzr upgrade on the repository."
3464
containing_tree.add_reference(sub_tree)
3465
except errors.BadReferenceTarget, e:
3466
# XXX: Would be better to just raise a nicely printable
3467
# exception from the real origin. Also below. mbp 20070306
3468
raise errors.BzrCommandError("Cannot join %s. %s" %
3472
containing_tree.subsume(sub_tree)
3473
except errors.BadSubsumeSource, e:
3474
raise errors.BzrCommandError("Cannot join %s. %s" %
3478
class cmd_split(Command):
3479
"""Split a tree into two trees.
3481
This command is for experimental use only. It requires the target tree
3482
to be in dirstate-with-subtree format, which cannot be converted into
3485
The TREE argument should be a subdirectory of a working tree. That
3486
subdirectory will be converted into an independent tree, with its own
3487
branch. Commits in the top-level tree will not apply to the new subtree.
3488
If you want that behavior, do "bzr join --reference TREE".
3491
_see_also = ['join']
3492
takes_args = ['tree']
3496
def run(self, tree):
3497
containing_tree, subdir = WorkingTree.open_containing(tree)
3498
sub_id = containing_tree.path2id(subdir)
3500
raise errors.NotVersionedError(subdir)
3502
containing_tree.extract(sub_id)
3503
except errors.RootNotRich:
3504
raise errors.UpgradeRequired(containing_tree.branch.base)
3508
class cmd_merge_directive(Command):
3509
"""Generate a merge directive for auto-merge tools.
3511
A directive requests a merge to be performed, and also provides all the
3512
information necessary to do so. This means it must either include a
3513
revision bundle, or the location of a branch containing the desired
3516
A submit branch (the location to merge into) must be supplied the first
3517
time the command is issued. After it has been supplied once, it will
3518
be remembered as the default.
3520
A public branch is optional if a revision bundle is supplied, but required
3521
if --diff or --plain is specified. It will be remembered as the default
3522
after the first use.
3525
takes_args = ['submit_branch?', 'public_branch?']
3528
RegistryOption.from_kwargs('patch-type',
3529
'The type of patch to include in the directive',
3530
title='Patch type', value_switches=True, enum_switch=False,
3531
bundle='Bazaar revision bundle (default)',
3532
diff='Normal unified diff',
3533
plain='No patch, just directive'),
3534
Option('sign', help='GPG-sign the directive'), 'revision',
3535
Option('mail-to', type=str,
3536
help='Instead of printing the directive, email to this address'),
3537
Option('message', type=str, short_name='m',
3538
help='Message to use when committing this merge')
3541
encoding_type = 'exact'
3543
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3544
sign=False, revision=None, mail_to=None, message=None):
3545
from bzrlib.revision import ensure_null, NULL_REVISION
3546
if patch_type == 'plain':
3548
branch = Branch.open('.')
3549
stored_submit_branch = branch.get_submit_branch()
3550
if submit_branch is None:
3551
submit_branch = stored_submit_branch
3553
if stored_submit_branch is None:
3554
branch.set_submit_branch(submit_branch)
3555
if submit_branch is None:
3556
submit_branch = branch.get_parent()
3557
if submit_branch is None:
3558
raise errors.BzrCommandError('No submit branch specified or known')
3560
stored_public_branch = branch.get_public_branch()
3561
if public_branch is None:
3562
public_branch = stored_public_branch
3563
elif stored_public_branch is None:
3564
branch.set_public_branch(public_branch)
3565
if patch_type != "bundle" and public_branch is None:
3566
raise errors.BzrCommandError('No public branch specified or'
3568
if revision is not None:
3569
if len(revision) != 1:
3570
raise errors.BzrCommandError('bzr merge-directive takes '
3571
'exactly one revision identifier')
3573
revision_id = revision[0].in_history(branch).rev_id
3575
revision_id = branch.last_revision()
3576
revision_id = ensure_null(revision_id)
3577
if revision_id == NULL_REVISION:
3578
raise errors.BzrCommandError('No revisions to bundle.')
3579
directive = merge_directive.MergeDirective.from_objects(
3580
branch.repository, revision_id, time.time(),
3581
osutils.local_time_offset(), submit_branch,
3582
public_branch=public_branch, patch_type=patch_type,
3586
self.outf.write(directive.to_signed(branch))
3588
self.outf.writelines(directive.to_lines())
3590
message = directive.to_email(mail_to, branch, sign)
3591
s = SMTPConnection(branch.get_config())
3592
s.send_email(message)
3595
class cmd_tag(Command):
3596
"""Create a tag naming a revision.
3598
Tags give human-meaningful names to revisions. Commands that take a -r
3599
(--revision) option can be given -rtag:X, where X is any previously
3602
Tags are stored in the branch. Tags are copied from one branch to another
3603
along when you branch, push, pull or merge.
3605
It is an error to give a tag name that already exists unless you pass
3606
--force, in which case the tag is moved to point to the new revision.
3609
_see_also = ['commit', 'tags']
3610
takes_args = ['tag_name']
3613
help='Delete this tag rather than placing it.',
3616
help='Branch in which to place the tag.',
3621
help='Replace existing tags',
3626
def run(self, tag_name,
3632
branch, relpath = Branch.open_containing(directory)
3636
branch.tags.delete_tag(tag_name)
3637
self.outf.write('Deleted tag %s.\n' % tag_name)
3640
if len(revision) != 1:
3641
raise errors.BzrCommandError(
3642
"Tags can only be placed on a single revision, "
3644
revision_id = revision[0].in_history(branch).rev_id
3646
revision_id = branch.last_revision()
3647
if (not force) and branch.tags.has_tag(tag_name):
3648
raise errors.TagAlreadyExists(tag_name)
3649
branch.tags.set_tag(tag_name, revision_id)
3650
self.outf.write('Created tag %s.\n' % tag_name)
3655
class cmd_tags(Command):
3658
This tag shows a table of tag names and the revisions they reference.
3664
help='Branch whose tags should be displayed',
3674
branch, relpath = Branch.open_containing(directory)
3675
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3676
self.outf.write('%-20s %s\n' % (tag_name, target))
2870
3679
# command-line interpretation helper for merge-related commands
2871
def merge(other_revision, base_revision,
2872
check_clean=True, ignore_zero=False,
2873
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2874
file_list=None, show_base=False, reprocess=False,
2875
pb=DummyProgress()):
3680
def _merge_helper(other_revision, base_revision,
3681
check_clean=True, ignore_zero=False,
3682
this_dir=None, backup_files=False,
3684
file_list=None, show_base=False, reprocess=False,
3687
change_reporter=None,
2876
3689
"""Merge changes into a tree.
2900
3713
clients might prefer to call merge.merge_inner(), which has less magic
2903
from bzrlib.merge import Merger
3716
# Loading it late, so that we don't always have to import bzrlib.merge
3717
if merge_type is None:
3718
merge_type = _mod_merge.Merge3Merger
2904
3719
if this_dir is None:
2905
3720
this_dir = u'.'
2906
3721
this_tree = WorkingTree.open_containing(this_dir)[0]
2907
if show_base and not merge_type is Merge3Merger:
2908
raise BzrCommandError("Show-base is not supported for this merge"
2909
" type. %s" % merge_type)
3722
if show_base and not merge_type is _mod_merge.Merge3Merger:
3723
raise errors.BzrCommandError("Show-base is not supported for this merge"
3724
" type. %s" % merge_type)
2910
3725
if reprocess and not merge_type.supports_reprocess:
2911
raise BzrCommandError("Conflict reduction is not supported for merge"
2912
" type %s." % merge_type)
3726
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3727
" type %s." % merge_type)
2913
3728
if reprocess and show_base:
2914
raise BzrCommandError("Cannot do conflict reduction and show base.")
3729
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3730
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3731
# only want to take out a lock_tree_write() if we don't have to pull
3732
# any ancestry. But merge might fetch ancestry in the middle, in
3733
# which case we would need a lock_write().
3734
# Because we cannot upgrade locks, for now we live with the fact that
3735
# the tree will be locked multiple times during a merge. (Maybe
3736
# read-only some of the time, but it means things will get read
2916
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
3739
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3740
pb=pb, change_reporter=change_reporter)
2917
3741
merger.pp = ProgressPhase("Merge phase", 5, pb)
2918
3742
merger.pp.next_phase()
2919
3743
merger.check_basis(check_clean)
2920
merger.set_other(other_revision)
3744
if other_rev_id is not None:
3745
merger.set_other_revision(other_rev_id, this_tree.branch)
3747
merger.set_other(other_revision)
2921
3748
merger.pp.next_phase()
2922
3749
merger.set_base(base_revision)
2923
3750
if merger.base_rev_id == merger.other_rev_id:
2924
3751
note('Nothing to do.')
3753
if file_list is None:
3754
if pull and merger.base_rev_id == merger.this_rev_id:
3755
# FIXME: deduplicate with pull
3756
result = merger.this_tree.pull(merger.this_branch,
3757
False, merger.other_rev_id)
3758
if result.old_revid == result.new_revid:
3759
note('No revisions to pull.')
3761
note('Now on revision %d.' % result.new_revno)
2926
3763
merger.backup_files = backup_files
2927
3764
merger.merge_type = merge_type
2928
3765
merger.set_interesting_files(file_list)