17
17
"""builtin bzr commands"""
20
from StringIO import StringIO
22
from bzrlib.lazy_import import lazy_import
23
lazy_import(globals(), """
32
27
from bzrlib import (
54
from bzrlib.branch import Branch
41
from bzrlib.branch import Branch, BranchReferenceFormat
42
from bzrlib.bundle import read_bundle_from_url
55
43
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
56
44
from bzrlib.conflicts import ConflictList
45
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
52
from bzrlib.progress import DummyProgress, ProgressPhase
57
53
from bzrlib.revision import common_ancestor
58
54
from bzrlib.revisionspec import RevisionSpec
55
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
56
from bzrlib.transport.local import LocalTransport
59
57
from bzrlib.workingtree import WorkingTree
62
from bzrlib.commands import Command, display_command
63
from bzrlib.option import ListOption, Option, RegistryOption
64
from bzrlib.progress import DummyProgress, ProgressPhase
65
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
68
60
def tree_files(file_list, default_branch=u'.'):
70
62
return internal_tree_files(file_list, default_branch)
71
except errors.FileInWrongBranch, e:
72
raise errors.BzrCommandError("%s is not in the same branch as %s" %
73
(e.path, file_list[0]))
63
except FileInWrongBranch, e:
64
raise BzrCommandError("%s is not in the same branch as %s" %
65
(e.path, file_list[0]))
76
68
# XXX: Bad function name; should possibly also be a class method of
343
275
--dry-run will show which files would be added, but not actually
346
--file-ids-from will try to use the file ids from the supplied path.
347
It looks up ids trying to find a matching parent directory with the
348
same filename, and then by pure path. This option is rarely needed
349
but can be useful when adding the same logical file into two
350
branches that will be merged later (without showing the two different
351
adds as a conflict). It is also useful when merging another project
352
into a subdirectory of this one.
354
278
takes_args = ['file*']
355
takes_options = ['no-recurse', 'dry-run', 'verbose',
356
Option('file-ids-from', type=unicode,
357
help='Lookup file ids from here')]
279
takes_options = ['no-recurse', 'dry-run', 'verbose']
358
280
encoding_type = 'replace'
359
_see_also = ['remove']
361
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
282
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
363
283
import bzrlib.add
366
if file_ids_from is not None:
368
base_tree, base_path = WorkingTree.open_containing(
370
except errors.NoWorkingTree:
371
base_branch, base_path = Branch.open_containing(
373
base_tree = base_branch.basis_tree()
375
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
376
to_file=self.outf, should_print=(not is_quiet()))
378
action = bzrlib.add.AddAction(to_file=self.outf,
379
should_print=(not is_quiet()))
382
base_tree.lock_read()
384
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
385
action=action, save=not dry_run)
387
if base_tree is not None:
285
action = bzrlib.add.AddAction(to_file=self.outf,
286
should_print=(not is_quiet()))
288
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
289
action=action, save=not dry_run)
389
290
if len(ignored) > 0:
391
292
for glob in sorted(ignored.keys()):
437
338
"""Show inventory of the current working copy or a revision.
439
340
It is possible to limit the output to a particular entry
440
type using the --kind option. For example: --kind file.
442
It is also possible to restrict the list of files to a specific
443
set. For example: bzr inventory --show-ids this/file
341
type using the --kind option. For example; --kind file.
448
344
takes_options = ['revision', 'show-ids', 'kind']
449
takes_args = ['file*']
452
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
347
def run(self, revision=None, show_ids=False, kind=None):
453
348
if kind and kind not in ['file', 'directory', 'symlink']:
454
raise errors.BzrCommandError('invalid kind specified')
456
work_tree, file_list = tree_files(file_list)
457
work_tree.lock_read()
459
if revision is not None:
460
if len(revision) > 1:
461
raise errors.BzrCommandError(
462
'bzr inventory --revision takes exactly one revision'
464
revision_id = revision[0].in_history(work_tree.branch).rev_id
465
tree = work_tree.branch.repository.revision_tree(revision_id)
467
extra_trees = [work_tree]
473
if file_list is not None:
474
file_ids = tree.paths2ids(file_list, trees=extra_trees,
475
require_versioned=True)
476
# find_ids_across_trees may include some paths that don't
478
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
479
for file_id in file_ids if file_id in tree)
481
entries = tree.inventory.entries()
484
if tree is not work_tree:
487
for path, entry in entries:
349
raise BzrCommandError('invalid kind specified')
350
tree = WorkingTree.open_containing(u'.')[0]
352
inv = tree.read_working_inventory()
354
if len(revision) > 1:
355
raise BzrCommandError('bzr inventory --revision takes'
356
' exactly one revision identifier')
357
inv = tree.branch.repository.get_revision_inventory(
358
revision[0].in_history(tree.branch).rev_id)
360
for path, entry in inv.entries():
488
361
if kind and kind != entry.kind:
562
425
location can be accessed.
565
_see_also = ['push', 'update']
566
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
568
help='branch to pull into, '
569
'rather than the one containing the working directory',
428
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
574
429
takes_args = ['location?']
575
430
encoding_type = 'replace'
577
def run(self, location=None, remember=False, overwrite=False,
578
revision=None, verbose=False,
580
from bzrlib.tag import _merge_tags_if_possible
432
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
581
433
# FIXME: too much stuff is in the command class
584
if directory is None:
587
tree_to = WorkingTree.open_containing(directory)[0]
435
tree_to = WorkingTree.open_containing(u'.')[0]
588
436
branch_to = tree_to.branch
589
except errors.NoWorkingTree:
437
except NoWorkingTree:
591
branch_to = Branch.open_containing(directory)[0]
439
branch_to = Branch.open_containing(u'.')[0]
594
442
if location is not None:
596
mergeable = bundle.read_mergeable_from_url(
598
except errors.NotABundle:
444
reader = bundle.read_bundle_from_url(location)
599
446
pass # Continue on considering this url a Branch
601
448
stored_loc = branch_to.get_parent()
602
449
if location is None:
603
450
if stored_loc is None:
604
raise errors.BzrCommandError("No pull location known or"
451
raise BzrCommandError("No pull location known or specified.")
607
453
display_url = urlutils.unescape_for_display(stored_loc,
608
454
self.outf.encoding)
609
455
self.outf.write("Using saved location: %s\n" % display_url)
610
456
location = stored_loc
612
if mergeable is not None:
613
if revision is not None:
614
raise errors.BzrCommandError(
615
'Cannot use -r with merge directives or bundles')
616
revision_id = mergeable.install_revisions(branch_to.repository)
459
if reader is not None:
460
install_bundle(branch_to.repository, reader)
617
461
branch_from = branch_to
619
463
branch_from = Branch.open(location)
711
542
to_transport = transport.get_transport(location)
712
543
location_url = to_transport.base
714
br_to = repository_to = dir_to = None
716
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
717
except errors.NotBranchError:
718
pass # Didn't find anything
720
# If we can open a branch, use its direct repository, otherwise see
721
# if there is a repository without a branch.
723
br_to = dir_to.open_branch()
724
except errors.NotBranchError:
725
# Didn't find a branch, can we find a repository?
727
repository_to = dir_to.find_repository()
728
except errors.NoRepositoryPresent:
731
# Found a branch, so we must have found a repository
732
repository_to = br_to.repository
736
# The destination doesn't exist; create it.
737
# XXX: Refactor the create_prefix/no_create_prefix code into a
738
# common helper function
740
to_transport.mkdir('.')
741
except errors.FileExists:
742
if not use_existing_dir:
743
raise errors.BzrCommandError("Target directory %s"
744
" already exists, but does not have a valid .bzr"
745
" directory. Supply --use-existing-dir to push"
746
" there anyway." % location)
747
except errors.NoSuchFile:
748
if not create_prefix:
749
raise errors.BzrCommandError("Parent directory of %s"
751
"\nYou may supply --create-prefix to create all"
752
" leading parent directories."
755
cur_transport = to_transport
756
needed = [cur_transport]
757
# Recurse upwards until we can create a directory successfully
759
new_transport = cur_transport.clone('..')
760
if new_transport.base == cur_transport.base:
761
raise errors.BzrCommandError("Failed to create path"
765
new_transport.mkdir('.')
766
except errors.NoSuchFile:
767
needed.append(new_transport)
768
cur_transport = new_transport
772
# Now we only need to create child directories
547
dir_to = bzrdir.BzrDir.open(location_url)
548
br_to = dir_to.open_branch()
549
except NotBranchError:
551
to_transport = to_transport.clone('..')
552
if not create_prefix:
554
relurl = to_transport.relpath(location_url)
555
mutter('creating directory %s => %s', location_url, relurl)
556
to_transport.mkdir(relurl)
558
raise BzrCommandError("Parent directory of %s "
559
"does not exist." % location)
561
current = to_transport.base
562
needed = [(to_transport, to_transport.relpath(location_url))]
774
cur_transport = needed.pop()
775
cur_transport.mkdir('.')
777
# Now the target directory exists, but doesn't have a .bzr
778
# directory. So we need to create it, along with any work to create
779
# all of the dependent branches, etc.
565
to_transport, relpath = needed[-1]
566
to_transport.mkdir(relpath)
569
new_transport = to_transport.clone('..')
570
needed.append((new_transport,
571
new_transport.relpath(to_transport.base)))
572
if new_transport.base == to_transport.base:
573
raise BzrCommandError("Could not create "
780
575
dir_to = br_from.bzrdir.clone(location_url,
781
576
revision_id=br_from.last_revision())
782
577
br_to = dir_to.open_branch()
783
# TODO: Some more useful message about what was copied
784
note('Created new branch.')
578
count = len(br_to.revision_history())
785
579
# We successfully created the target, remember it
786
580
if br_from.get_push_location() is None or remember:
787
581
br_from.set_push_location(br_to.base)
788
elif repository_to is None:
789
# we have a bzrdir but no branch or repository
790
# XXX: Figure out what to do other than complain.
791
raise errors.BzrCommandError("At %s you have a valid .bzr control"
792
" directory, but not a branch or repository. This is an"
793
" unsupported configuration. Please move the target directory"
794
" out of the way and try again."
797
# We have a repository but no branch, copy the revisions, and then
799
last_revision_id = br_from.last_revision()
800
repository_to.fetch(br_from.repository,
801
revision_id=last_revision_id)
802
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
803
note('Created new branch.')
804
if br_from.get_push_location() is None or remember:
805
br_from.set_push_location(br_to.base)
806
else: # We have a valid to branch
807
583
# We were able to connect to the remote location, so remember it
808
584
# we don't need to successfully push because of possible divergence.
809
585
if br_from.get_push_location() is None or remember:
1085
865
also new, they will also be removed.
1087
867
takes_args = ['file*']
1088
takes_options = ['verbose',
1089
Option('new', help='remove newly-added files'),
1090
RegistryOption.from_kwargs('file-deletion-strategy',
1091
'The file deletion mode to be used',
1092
title='Deletion Strategy', value_switches=True, enum_switch=False,
1093
safe='Only delete files if they can be'
1094
' safely recovered (default).',
1095
keep="Don't delete any files.",
1096
force='Delete all the specified files, even if they can not be '
1097
'recovered and even if they are non-empty directories.')]
868
takes_options = ['verbose', Option('new', help='remove newly-added files')]
1098
869
aliases = ['rm']
1099
870
encoding_type = 'replace'
1101
def run(self, file_list, verbose=False, new=False,
1102
file_deletion_strategy='safe'):
872
def run(self, file_list, verbose=False, new=False):
1103
873
tree, file_list = tree_files(file_list)
1105
if file_list is not None:
1106
file_list = [f for f in file_list if f != '']
1108
raise errors.BzrCommandError('Specify one or more files to'
1109
' remove, or use --new.')
875
if file_list is None:
876
raise BzrCommandError('Specify one or more files to remove, or'
1112
879
added = tree.changes_from(tree.basis_tree(),
1113
880
specific_files=file_list).added
1114
881
file_list = sorted([f[0] for f in added], reverse=True)
1115
882
if len(file_list) == 0:
1116
raise errors.BzrCommandError('No matching files.')
1117
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1118
keep_files=file_deletion_strategy=='keep',
1119
force=file_deletion_strategy=='force')
883
raise BzrCommandError('No matching files.')
884
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1122
887
class cmd_file_id(Command):
1293
1043
existing_bzrdir = bzrdir.BzrDir.open(location)
1294
except errors.NotBranchError:
1044
except NotBranchError:
1295
1045
# really a NotBzrDir error...
1296
branch = bzrdir.BzrDir.create_branch_convenience(to_transport.base,
1046
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1299
from bzrlib.transport.local import LocalTransport
1300
1048
if existing_bzrdir.has_branch():
1301
1049
if (isinstance(to_transport, LocalTransport)
1302
1050
and not existing_bzrdir.has_workingtree()):
1303
1051
raise errors.BranchExistsWithoutWorkingTree(location)
1304
1052
raise errors.AlreadyBranchError(location)
1306
branch = existing_bzrdir.create_branch()
1054
existing_bzrdir.create_branch()
1307
1055
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')
1316
1058
class cmd_init_repository(Command):
1317
1059
"""Create a shared repository to hold branches.
1319
1061
New branches created under the repository directory will store their revisions
1320
in the repository, not in the branch directory.
1062
in the repository, not in the branch directory, if the branch format supports
1323
bzr init-repo --no-trees repo
1324
1067
bzr init repo/trunk
1325
1068
bzr checkout --lightweight repo/trunk trunk-checkout
1326
1069
cd trunk-checkout
1327
1070
(add files here)
1330
_see_also = ['init', 'branch', 'checkout']
1331
takes_args = ["location"]
1332
takes_options = [RegistryOption('format',
1333
help='Specify a format for this repository. See'
1334
' "bzr help formats" for details',
1335
registry=bzrdir.format_registry,
1336
converter=bzrdir.format_registry.make_bzrdir,
1337
value_switches=True, title='Repository format'),
1339
help='Branches in the repository will default to'
1340
' not having a working tree'),
1072
takes_args = ["location"]
1073
takes_options = [Option('format',
1074
help='Specify a format for this repository.'
1075
' Current formats are: default, knit,'
1076
' metaweave and weave. Default is knit;'
1077
' metaweave and weave are deprecated',
1078
type=get_format_type),
1080
help='Allows branches in repository to have'
1342
1082
aliases = ["init-repo"]
1344
def run(self, location, format=None, no_trees=False):
1083
def run(self, location, format=None, trees=False):
1345
1084
if format is None:
1346
format = bzrdir.format_registry.make_bzrdir('default')
1085
format = get_format_type('default')
1348
1087
if location is None:
1616
1322
# find the file id to log:
1618
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1324
dir, fp = bzrdir.BzrDir.open_containing(location)
1325
b = dir.open_branch()
1622
tree = b.basis_tree()
1623
file_id = tree.path2id(fp)
1625
raise errors.BzrCommandError(
1626
"Path does not have any revision history: %s" %
1329
inv = dir.open_workingtree().inventory
1330
except (errors.NotBranchError, errors.NotLocalUrl):
1331
# either no tree, or is remote.
1332
inv = b.basis_tree().inventory
1333
file_id = inv.path2id(fp)
1629
1335
# local dir only
1630
1336
# FIXME ? log the current subdir only RBC 20060203
1631
if revision is not None \
1632
and len(revision) > 0 and revision[0].get_branch():
1633
location = revision[0].get_branch()
1636
dir, relpath = bzrdir.BzrDir.open_containing(location)
1337
dir, relpath = bzrdir.BzrDir.open_containing('.')
1637
1338
b = dir.open_branch()
1641
if revision is None:
1644
elif len(revision) == 1:
1645
rev1 = rev2 = revision[0].in_history(b).revno
1646
elif len(revision) == 2:
1647
if revision[1].get_branch() != revision[0].get_branch():
1648
# b is taken from revision[0].get_branch(), and
1649
# show_log will use its revision_history. Having
1650
# different branches will lead to weird behaviors.
1651
raise errors.BzrCommandError(
1652
"Log doesn't accept two revisions in different"
1654
if revision[0].spec is None:
1655
# missing begin-range means first revision
1658
rev1 = revision[0].in_history(b).revno
1660
if revision[1].spec is None:
1661
# missing end-range means last known revision
1664
rev2 = revision[1].in_history(b).revno
1666
raise errors.BzrCommandError(
1667
'bzr log --revision takes one or two values.')
1669
# By this point, the revision numbers are converted to the +ve
1670
# form if they were supplied in the -ve form, so we can do
1671
# this comparison in relative safety
1673
(rev2, rev1) = (rev1, rev2)
1675
if log_format is None:
1676
log_format = log.log_formatter_registry.get_default(b)
1678
lf = log_format(show_ids=show_ids, to_file=self.outf,
1679
show_timezone=timezone)
1685
direction=direction,
1686
start_revision=rev1,
1340
if revision is None:
1343
elif len(revision) == 1:
1344
rev1 = rev2 = revision[0].in_history(b).revno
1345
elif len(revision) == 2:
1346
if revision[0].spec is None:
1347
# missing begin-range means first revision
1350
rev1 = revision[0].in_history(b).revno
1352
if revision[1].spec is None:
1353
# missing end-range means last known revision
1356
rev2 = revision[1].in_history(b).revno
1358
raise BzrCommandError('bzr log --revision takes one or two values.')
1360
# By this point, the revision numbers are converted to the +ve
1361
# form if they were supplied in the -ve form, so we can do
1362
# this comparison in relative safety
1364
(rev2, rev1) = (rev1, rev2)
1366
if (log_format == None):
1367
default = b.get_config().log_format()
1368
log_format = get_log_format(long=long, short=short, line=line,
1370
lf = log_formatter(log_format,
1373
show_timezone=timezone)
1379
direction=direction,
1380
start_revision=rev1,
1693
1385
def get_log_format(long=False, short=False, line=False, default='long'):
1736
1427
Option('ignored', help='Print ignored files'),
1738
1429
Option('null', help='Null separate the files'),
1741
1431
@display_command
1742
1432
def run(self, revision=None, verbose=False,
1743
1433
non_recursive=False, from_root=False,
1744
1434
unknown=False, versioned=False, ignored=False,
1745
null=False, kind=None, show_ids=False, path=None):
1747
if kind and kind not in ('file', 'directory', 'symlink'):
1748
raise errors.BzrCommandError('invalid kind specified')
1750
1437
if verbose and null:
1751
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1438
raise BzrCommandError('Cannot set both --verbose and --null')
1752
1439
all = not (unknown or versioned or ignored)
1754
1441
selection = {'I':ignored, '?':unknown, 'V':versioned}
1761
raise errors.BzrCommandError('cannot specify both --from-root'
1765
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1443
tree, relpath = WorkingTree.open_containing(u'.')
1771
1448
if revision is not None:
1772
tree = branch.repository.revision_tree(
1773
revision[0].in_history(branch).rev_id)
1775
tree = branch.basis_tree()
1449
tree = tree.branch.repository.revision_tree(
1450
revision[0].in_history(tree.branch).rev_id)
1779
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1780
if fp.startswith(relpath):
1781
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1782
if non_recursive and '/' in fp:
1784
if not all and not selection[fc]:
1786
if kind is not None and fkind != kind:
1789
kindch = entry.kind_character()
1790
outstring = '%-8s %s%s' % (fc, fp, kindch)
1791
if show_ids and fid is not None:
1792
outstring = "%-50s %s" % (outstring, fid)
1793
self.outf.write(outstring + '\n')
1795
self.outf.write(fp + '\0')
1798
self.outf.write(fid)
1799
self.outf.write('\0')
1807
self.outf.write('%-50s %s\n' % (fp, my_id))
1809
self.outf.write(fp + '\n')
1452
for fp, fc, kind, fid, entry in tree.list_files():
1453
if fp.startswith(relpath):
1454
fp = fp[len(relpath):]
1455
if non_recursive and '/' in fp:
1457
if not all and not selection[fc]:
1460
kindch = entry.kind_character()
1461
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1463
self.outf.write(fp + '\0')
1466
self.outf.write(fp + '\n')
1814
1469
class cmd_unknowns(Command):
1815
"""List unknown files.
1470
"""List unknown files."""
1821
1471
@display_command
1823
1473
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1827
1477
class cmd_ignore(Command):
1828
"""Ignore specified files or patterns.
1478
"""Ignore a command or pattern.
1830
1480
To remove patterns from the ignore list, edit the .bzrignore file.
1832
Trailing slashes on patterns are ignored.
1833
If the pattern contains a slash or is a regular expression, it is compared
1834
to the whole path from the branch root. Otherwise, it is compared to only
1835
the last component of the path. To match a file only in the root
1836
directory, prepend './'.
1838
Ignore patterns specifying absolute paths are not allowed.
1840
Ignore patterns may include globbing wildcards such as:
1841
? - Matches any single character except '/'
1842
* - Matches 0 or more characters except '/'
1843
/**/ - Matches 0 or more directories in a path
1844
[a-z] - Matches a single character from within a group of characters
1846
Ignore patterns may also be Python regular expressions.
1847
Regular expression ignore patterns are identified by a 'RE:' prefix
1848
followed by the regular expression. Regular expression ignore patterns
1849
may not include named or numbered groups.
1851
Note: ignore patterns containing shell wildcards must be quoted from
1482
If the pattern contains a slash, it is compared to the whole path
1483
from the branch root. Otherwise, it is compared to only the last
1484
component of the path. To match a file only in the root directory,
1487
Ignore patterns are case-insensitive on case-insensitive systems.
1489
Note: wildcards must be quoted from the shell on Unix.
1855
1492
bzr ignore ./Makefile
1856
1493
bzr ignore '*.class'
1857
bzr ignore 'lib/**/*.o'
1858
bzr ignore 'RE:lib/.*\.o'
1861
_see_also = ['status', 'ignored']
1862
takes_args = ['name_pattern*']
1495
# TODO: Complain if the filename is absolute
1496
takes_args = ['name_pattern?']
1863
1497
takes_options = [
1864
1498
Option('old-default-rules',
1865
1499
help='Out the ignore rules bzr < 0.9 always used.')
1868
def run(self, name_pattern_list=None, old_default_rules=None):
1502
def run(self, name_pattern=None, old_default_rules=None):
1869
1503
from bzrlib.atomicfile import AtomicFile
1870
1504
if old_default_rules is not None:
1871
1505
# dump the rules and exit
1872
1506
for pattern in ignores.OLD_DEFAULTS:
1875
if not name_pattern_list:
1876
raise errors.BzrCommandError("ignore requires at least one "
1877
"NAME_PATTERN or --old-default-rules")
1878
name_pattern_list = [globbing.normalize_pattern(p)
1879
for p in name_pattern_list]
1880
for name_pattern in name_pattern_list:
1881
if (name_pattern[0] == '/' or
1882
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1883
raise errors.BzrCommandError(
1884
"NAME_PATTERN should not be an absolute path")
1509
if name_pattern is None:
1510
raise BzrCommandError("ignore requires a NAME_PATTERN")
1885
1511
tree, relpath = WorkingTree.open_containing(u'.')
1886
1512
ifn = tree.abspath('.bzrignore')
1887
1513
if os.path.exists(ifn):
1977
1597
tgz .tar.gz, .tgz
1980
takes_args = ['dest', 'branch?']
1600
takes_args = ['dest']
1981
1601
takes_options = ['revision', 'format', 'root']
1982
def run(self, dest, branch=None, revision=None, format=None, root=None):
1602
def run(self, dest, revision=None, format=None, root=None):
1983
1603
from bzrlib.export import export
1986
tree = WorkingTree.open_containing(u'.')[0]
1989
b = Branch.open(branch)
1604
tree = WorkingTree.open_containing(u'.')[0]
1991
1606
if revision is None:
1992
1607
# should be tree.last_revision FIXME
1993
1608
rev_id = b.last_revision()
1995
1610
if len(revision) != 1:
1996
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1611
raise BzrError('bzr export --revision takes exactly 1 argument')
1997
1612
rev_id = revision[0].in_history(b).rev_id
1998
1613
t = b.repository.revision_tree(rev_id)
2000
1615
export(t, dest, format, root)
2001
1616
except errors.NoSuchExportFormat, e:
2002
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1617
raise BzrCommandError('Unsupported export format: %s' % e.format)
2005
1620
class cmd_cat(Command):
2006
"""Write the contents of a file as of a given revision to standard output.
2008
If no revision is nominated, the last revision is used.
2010
Note: Take care to redirect standard output when using this command on a
2015
takes_options = ['revision', 'name-from-revision']
1621
"""Write a file's text from a previous revision."""
1623
takes_options = ['revision']
2016
1624
takes_args = ['filename']
2017
encoding_type = 'exact'
2019
1626
@display_command
2020
def run(self, filename, revision=None, name_from_revision=False):
1627
def run(self, filename, revision=None):
2021
1628
if revision is not None and len(revision) != 1:
2022
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1629
raise BzrCommandError("bzr cat --revision takes exactly one number")
2027
tree, b, relpath = \
2028
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2029
except errors.NotBranchError:
1632
tree, relpath = WorkingTree.open_containing(filename)
1634
except NotBranchError:
2032
if revision is not None and revision[0].get_branch() is not None:
2033
b = Branch.open(revision[0].get_branch())
2034
1637
if tree is None:
2035
tree = b.basis_tree()
1638
b, relpath = Branch.open_containing(filename)
2036
1639
if revision is None:
2037
1640
revision_id = b.last_revision()
2039
1642
revision_id = revision[0].in_history(b).rev_id
2041
cur_file_id = tree.path2id(relpath)
2042
rev_tree = b.repository.revision_tree(revision_id)
2043
old_file_id = rev_tree.path2id(relpath)
2045
if name_from_revision:
2046
if old_file_id is None:
2047
raise errors.BzrCommandError("%r is not present in revision %s"
2048
% (filename, revision_id))
2050
rev_tree.print_file(old_file_id)
2051
elif cur_file_id is not None:
2052
rev_tree.print_file(cur_file_id)
2053
elif old_file_id is not None:
2054
rev_tree.print_file(old_file_id)
2056
raise errors.BzrCommandError("%r is not present in revision %s" %
2057
(filename, revision_id))
1643
b.print_file(relpath, revision_id)
2060
1646
class cmd_local_time_offset(Command):
2128
1694
aliases = ['ci', 'checkin']
2130
def _get_bug_fix_properties(self, fixes, branch):
2132
# Configure the properties for bug fixing attributes.
2133
for fixed_bug in fixes:
2134
tokens = fixed_bug.split(':')
2135
if len(tokens) != 2:
2136
raise errors.BzrCommandError(
2137
"Invalid bug %s. Must be in the form of 'tag:id'. "
2138
"Commit refused." % fixed_bug)
2139
tag, bug_id = tokens
2141
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2142
except errors.UnknownBugTrackerAbbreviation:
2143
raise errors.BzrCommandError(
2144
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2145
except errors.MalformedBugIdentifier:
2146
raise errors.BzrCommandError(
2147
"Invalid bug identifier for %s. Commit refused."
2149
properties.append('%s fixed' % bug_url)
2150
return '\n'.join(properties)
2152
1696
def run(self, message=None, file=None, verbose=True, selected_list=None,
2153
unchanged=False, strict=False, local=False, fixes=None):
1697
unchanged=False, strict=False, local=False):
2154
1698
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2155
1699
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2156
1700
StrictCommitFailed)
2157
1701
from bzrlib.msgeditor import edit_commit_message, \
2158
1702
make_commit_message_template
1703
from tempfile import TemporaryFile
2160
1705
# TODO: Need a blackbox test for invoking the external editor; may be
2161
1706
# slightly problematic to run this cross-platform.
2163
1708
# TODO: do more checks that the commit will succeed before
2164
1709
# spending the user's valuable time typing a commit message.
1711
# TODO: if the commit *does* happen to fail, then save the commit
1712
# message to a temporary file where it can be recovered
2168
1713
tree, selected_list = tree_files(selected_list)
2169
1714
if selected_list == ['']:
2170
1715
# workaround - commit of root of tree should be exactly the same
2172
1717
# selected-file merge commit is not done yet
2173
1718
selected_list = []
2175
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2177
properties['bugs'] = bug_property
2179
1720
if local and not tree.branch.get_bound_location():
2180
1721
raise errors.LocalRequiresBoundBranch()
2182
def get_message(commit_obj):
2183
"""Callback to get commit message"""
2184
my_message = message
2185
if my_message is None and not file:
2186
template = make_commit_message_template(tree, selected_list)
2187
my_message = edit_commit_message(template)
2188
if my_message is None:
2189
raise errors.BzrCommandError("please specify a commit"
2190
" message with either --message or --file")
2191
elif my_message and file:
2192
raise errors.BzrCommandError(
2193
"please specify either --message or --file")
2195
my_message = codecs.open(file, 'rt',
2196
bzrlib.user_encoding).read()
2197
if my_message == "":
2198
raise errors.BzrCommandError("empty commit message specified")
1722
if message is None and not file:
1723
template = make_commit_message_template(tree, selected_list)
1724
message = edit_commit_message(template)
1726
raise BzrCommandError("please specify a commit message"
1727
" with either --message or --file")
1728
elif message and file:
1729
raise BzrCommandError("please specify either --message or --file")
1732
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1735
raise BzrCommandError("empty commit message specified")
2202
1738
reporter = ReportCommitToLog()
2204
1740
reporter = NullCommitReporter()
2207
tree.commit(message_callback=get_message,
2208
specific_files=selected_list,
1743
tree.commit(message, specific_files=selected_list,
2209
1744
allow_pointless=unchanged, strict=strict, local=local,
2210
reporter=reporter, revprops=properties)
2211
1746
except PointlessCommit:
2212
1747
# FIXME: This should really happen before the file is read in;
2213
1748
# perhaps prepare the commit; get the message; then actually commit
2214
raise errors.BzrCommandError("no changes to commit."
2215
" use --unchanged to commit anyhow")
1749
raise BzrCommandError("no changes to commit."
1750
" use --unchanged to commit anyhow")
2216
1751
except ConflictsInTree:
2217
raise errors.BzrCommandError('Conflicts detected in working '
2218
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1752
raise BzrCommandError("Conflicts detected in working tree. "
1753
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
2220
1754
except StrictCommitFailed:
2221
raise errors.BzrCommandError("Commit refused because there are"
2222
" unknown files in the working tree.")
1755
raise BzrCommandError("Commit refused because there are unknown "
1756
"files in the working tree.")
2223
1757
except errors.BoundBranchOutOfDate, e:
2224
raise errors.BzrCommandError(str(e) + "\n"
2225
'To commit to master branch, run update and then commit.\n'
2226
'You can also pass --local to commit to continue working '
1758
raise BzrCommandError(str(e)
1759
+ ' Either unbind, update, or'
1760
' pass --local to commit.')
2230
1763
class cmd_check(Command):
2338
1885
@display_command
2339
1886
def printme(self, branch):
2343
1890
class cmd_selftest(Command):
2344
1891
"""Run internal test suite.
2346
This creates temporary test directories in the working directory, but no
2347
existing data is affected. These directories are deleted if the tests
2348
pass, or left behind to help in debugging if they fail and --keep-output
1893
This creates temporary test directories in the working directory,
1894
but not existing data is affected. These directories are deleted
1895
if the tests pass, or left behind to help in debugging if they
1896
fail and --keep-output is specified.
2351
If arguments are given, they are regular expressions that say which tests
2352
should run. Tests matching any expression are run, and other tests are
2355
Alternatively if --first is given, matching tests are run first and then
2356
all other tests are run. This is useful if you have been working in a
2357
particular area, but want to make sure nothing else was broken.
2359
If --exclude is given, tests that match that regular expression are
2360
excluded, regardless of whether they match --first or not.
2362
To help catch accidential dependencies between tests, the --randomize
2363
option is useful. In most cases, the argument used is the word 'now'.
2364
Note that the seed used for the random number generator is displayed
2365
when this option is used. The seed can be explicitly passed as the
2366
argument to this option if required. This enables reproduction of the
2367
actual ordering used if and when an order sensitive problem is encountered.
2369
If --list-only is given, the tests that would be run are listed. This is
2370
useful when combined with --first, --exclude and/or --randomize to
2371
understand their impact. The test harness reports "Listed nn tests in ..."
2372
instead of "Ran nn tests in ..." when list mode is enabled.
1898
If arguments are given, they are regular expressions that say
1899
which tests should run.
2374
1901
If the global option '--no-plugins' is given, plugins are not loaded
2375
1902
before running the selftests. This has two effects: features provided or
2376
1903
modified by plugins will not be tested, and tests provided by plugins will
2380
1907
bzr selftest ignore
2381
run only tests relating to 'ignore'
2382
1908
bzr --no-plugins selftest -v
2383
disable plugins and list tests as they're run
1910
# TODO: --list should give a list of all available tests
2385
For each test, that needs actual disk access, bzr create their own
2386
subdirectory in the temporary testing directory (testXXXX.tmp).
2387
By default the name of such subdirectory is based on the name of the test.
2388
If option '--numbered-dirs' is given, bzr will use sequent numbers
2389
of running tests to create such subdirectories. This is default behavior
2390
on Windows because of path length limitation.
2392
1912
# NB: this is used from the class without creating an instance, which is
2393
1913
# why it does not have a self parameter.
2394
1914
def get_transport_type(typestring):
2404
1924
return FakeNFSServer
2405
1925
msg = "No known transport type %s. Supported types are: sftp\n" %\
2407
raise errors.BzrCommandError(msg)
1927
raise BzrCommandError(msg)
2410
1930
takes_args = ['testspecs*']
2411
1931
takes_options = ['verbose',
2413
help='stop when one test fails',
2416
Option('keep-output',
1932
Option('one', help='stop when one test fails'),
1933
Option('keep-output',
2417
1934
help='keep output directories when tests fail'),
2419
1936
help='Use a different transport by default '
2420
1937
'throughout the test suite.',
2421
1938
type=get_transport_type),
2422
Option('benchmark', help='run the bzr benchmarks.'),
1939
Option('benchmark', help='run the bzr bencharks.'),
2423
1940
Option('lsprof-timed',
2424
1941
help='generate lsprof output for benchmarked'
2425
1942
' sections of code.'),
2426
Option('cache-dir', type=str,
2427
help='a directory to cache intermediate'
2428
' benchmark steps'),
2429
Option('clean-output',
2430
help='clean temporary tests directories'
2431
' without running tests'),
2433
help='run all tests, but run specified tests first',
2436
Option('numbered-dirs',
2437
help='use numbered dirs for TestCaseInTempDir'),
2439
help='list the tests instead of running them'),
2440
Option('randomize', type=str, argname="SEED",
2441
help='randomize the order of tests using the given'
2442
' seed or "now" for the current time'),
2443
Option('exclude', type=str, argname="PATTERN",
2445
help='exclude tests that match this regular'
2448
encoding_type = 'replace'
2450
1945
def run(self, testspecs_list=None, verbose=None, one=False,
2451
1946
keep_output=False, transport=None, benchmark=None,
2452
lsprof_timed=None, cache_dir=None, clean_output=False,
2453
first=False, numbered_dirs=None, list_only=False,
2454
randomize=None, exclude=None):
2455
1948
import bzrlib.ui
2456
1949
from bzrlib.tests import selftest
2457
1950
import bzrlib.benchmarks as benchmarks
2458
from bzrlib.benchmarks import tree_creator
2461
from bzrlib.tests import clean_selftest_output
2462
clean_selftest_output()
2465
if numbered_dirs is None and sys.platform == 'win32':
2466
numbered_dirs = True
2468
if cache_dir is not None:
2469
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
1951
# we don't want progress meters from the tests to go to the
1952
# real output; and we don't want log messages cluttering up
1954
save_ui = ui.ui_factory
2470
1955
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2471
1956
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2473
if testspecs_list is not None:
2474
pattern = '|'.join(testspecs_list)
2478
test_suite_factory = benchmarks.test_suite
2481
# TODO: should possibly lock the history file...
2482
benchfile = open(".perf_history", "at", buffering=1)
2484
test_suite_factory = None
1958
info('running tests...')
1960
ui.ui_factory = ui.SilentUIFactory()
1961
if testspecs_list is not None:
1962
pattern = '|'.join(testspecs_list)
1966
test_suite_factory = benchmarks.test_suite
1970
test_suite_factory = None
2489
1973
result = selftest(verbose=verbose,
2490
1974
pattern=pattern,
2491
1975
stop_on_failure=one,
2492
1976
keep_output=keep_output,
2493
1977
transport=transport,
2494
1978
test_suite_factory=test_suite_factory,
2495
lsprof_timed=lsprof_timed,
2496
bench_history=benchfile,
2497
matching_tests_first=first,
2498
numbered_dirs=numbered_dirs,
2499
list_only=list_only,
2500
random_seed=randomize,
2501
exclude_pattern=exclude
1979
lsprof_timed=lsprof_timed)
1981
info('tests passed')
1983
info('tests failed')
1984
return int(not result)
2504
if benchfile is not None:
2507
info('tests passed')
2509
info('tests failed')
2510
return int(not result)
1986
ui.ui_factory = save_ui
1989
def _get_bzr_branch():
1990
"""If bzr is run from a branch, return Branch or None"""
1991
from os.path import dirname
1994
branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1996
except errors.BzrError:
2002
print "Bazaar (bzr) %s" % bzrlib.__version__
2003
# is bzrlib itself in a branch?
2004
branch = _get_bzr_branch()
2006
rh = branch.revision_history()
2008
print " bzr checkout, revision %d" % (revno,)
2009
print " nick: %s" % (branch.nick,)
2011
print " revid: %s" % (rh[-1],)
2012
print "Using python interpreter:", sys.executable
2014
print "Using python standard library:", os.path.dirname(site.__file__)
2015
print "Using bzrlib:",
2016
if len(bzrlib.__path__) > 1:
2017
# print repr, which is a good enough way of making it clear it's
2018
# more than one element (eg ['/foo/bar', '/foo/bzr'])
2019
print repr(bzrlib.__path__)
2021
print bzrlib.__path__[0]
2024
print bzrlib.__copyright__
2025
print "http://bazaar-vcs.org/"
2027
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
2028
print "you may use, modify and redistribute it under the terms of the GNU"
2029
print "General Public License version 2 or later."
2513
2032
class cmd_version(Command):
2579
2100
default, use --remember. The value will only be saved if the remote
2580
2101
location can be accessed.
2582
The results of the merge are placed into the destination working
2583
directory, where they can be reviewed (with bzr diff), tested, and then
2584
committed to record the result of the merge.
2588
To merge the latest revision from bzr.dev:
2589
bzr merge ../bzr.dev
2105
To merge the latest revision from bzr.dev
2106
bzr merge ../bzr.dev
2591
To merge changes up to and including revision 82 from bzr.dev:
2592
bzr merge -r 82 ../bzr.dev
2108
To merge changes up to and including revision 82 from bzr.dev
2109
bzr merge -r 82 ../bzr.dev
2594
2111
To merge the changes introduced by 82, without previous changes:
2595
bzr merge -r 81..82 ../bzr.dev
2112
bzr merge -r 81..82 ../bzr.dev
2597
2114
merge refuses to run if there are any uncommitted changes, unless
2598
2115
--force is given.
2117
The following merge types are available:
2601
_see_also = ['update', 'remerge']
2602
2119
takes_args = ['branch?']
2603
2120
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2604
Option('show-base', help="Show base revision text in "
2606
Option('uncommitted', help='Apply uncommitted changes'
2607
' from a working copy, instead of branch changes'),
2608
Option('pull', help='If the destination is already'
2609
' completely merged into the source, pull from the'
2610
' source rather than merging. When this happens,'
2611
' you do not need to commit the result.'),
2613
help='Branch to merge into, '
2614
'rather than the one containing the working directory',
2121
Option('show-base', help="Show base revision text in "
2125
from merge import merge_type_help
2126
from inspect import getdoc
2127
return getdoc(self) + '\n' + merge_type_help()
2620
2129
def run(self, branch=None, revision=None, force=False, merge_type=None,
2621
show_base=False, reprocess=False, remember=False,
2622
uncommitted=False, pull=False,
2625
from bzrlib.tag import _merge_tags_if_possible
2626
other_revision_id = None
2130
show_base=False, reprocess=False, remember=False):
2627
2131
if merge_type is None:
2628
merge_type = _mod_merge.Merge3Merger
2132
merge_type = Merge3Merger
2630
if directory is None: directory = u'.'
2631
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2632
# inventory. Because merge is a mutating operation, it really
2633
# should be a lock_write() for the whole cmd_merge operation.
2634
# However, cmd_merge open's its own tree in _merge_helper, which
2635
# means if we lock here, the later lock_write() will always block.
2636
# Either the merge helper code should be updated to take a tree,
2637
# (What about tree.merge_from_branch?)
2638
tree = WorkingTree.open_containing(directory)[0]
2639
change_reporter = delta._ChangeReporter(
2640
unversioned_filter=tree.is_ignored)
2134
tree = WorkingTree.open_containing(u'.')[0]
2642
2136
if branch is not None:
2644
mergeable = bundle.read_mergeable_from_url(
2646
except errors.NotABundle:
2138
reader = bundle.read_bundle_from_url(branch)
2647
2140
pass # Continue on considering this url a Branch
2649
if revision is not None:
2650
raise errors.BzrCommandError(
2651
'Cannot use -r with merge directives or bundles')
2652
other_revision_id = mergeable.install_revisions(
2653
tree.branch.repository)
2654
revision = [RevisionSpec.from_string(
2655
'revid:' + other_revision_id)]
2142
conflicts = merge_bundle(reader, tree, not force, merge_type,
2143
reprocess, show_base)
2657
if revision is None \
2658
or len(revision) < 1 or revision[0].needs_branch():
2659
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2149
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2661
2151
if revision is None or len(revision) < 1:
2664
other = [branch, None]
2667
other = [branch, -1]
2153
other = [branch, -1]
2668
2154
other_branch, path = Branch.open_containing(branch)
2671
raise errors.BzrCommandError('Cannot use --uncommitted and'
2672
' --revision at the same time.')
2673
branch = revision[0].get_branch() or branch
2674
2156
if len(revision) == 1:
2675
2157
base = [None, None]
2676
if other_revision_id is not None:
2681
other_branch, path = Branch.open_containing(branch)
2682
revno = revision[0].in_history(other_branch).revno
2683
other = [branch, revno]
2158
other_branch, path = Branch.open_containing(branch)
2159
revno = revision[0].in_history(other_branch).revno
2160
other = [branch, revno]
2685
2162
assert len(revision) == 2
2686
2163
if None in revision:
2687
raise errors.BzrCommandError(
2688
"Merge doesn't permit empty revision specifier.")
2689
base_branch, path = Branch.open_containing(branch)
2690
branch1 = revision[1].get_branch() or branch
2691
other_branch, path1 = Branch.open_containing(branch1)
2692
if revision[0].get_branch() is not None:
2693
# then path was obtained from it, and is None.
2696
base = [branch, revision[0].in_history(base_branch).revno]
2697
other = [branch1, revision[1].in_history(other_branch).revno]
2699
if ((tree.branch.get_parent() is None or remember) and
2700
other_branch is not None):
2164
raise BzrCommandError(
2165
"Merge doesn't permit that revision specifier.")
2166
other_branch, path = Branch.open_containing(branch)
2168
base = [branch, revision[0].in_history(other_branch).revno]
2169
other = [branch, revision[1].in_history(other_branch).revno]
2171
if tree.branch.get_parent() is None or remember:
2701
2172
tree.branch.set_parent(other_branch.base)
2703
# pull tags now... it's a bit inconsistent to do it ahead of copying
2704
# the history but that's done inside the merge code
2705
if other_branch is not None:
2706
_merge_tags_if_possible(other_branch, tree.branch)
2709
2175
interesting_files = [path]
3161
2598
if to_revid is None:
3162
2599
to_revno = b.revno()
3163
2600
if from_revno is None or to_revno is None:
3164
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2601
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
3165
2602
for revno in range(from_revno, to_revno + 1):
3166
2603
b.repository.sign_revision(b.get_rev_id(revno),
3169
raise errors.BzrCommandError('Please supply either one revision, or a range.')
2606
raise BzrCommandError('Please supply either one revision, or a range.')
3172
2609
class cmd_bind(Command):
3173
"""Convert the current branch into a checkout of the supplied branch.
2610
"""Bind the current branch to a master branch.
3175
Once converted into a checkout, commits must succeed on the master branch
3176
before they will be applied to the local branch.
2612
After binding, commits must succeed on the master branch
2613
before they are executed on the local one.
3179
_see_also = ['checkouts', 'unbind']
3180
takes_args = ['location?']
2616
takes_args = ['location']
3181
2617
takes_options = []
3183
2619
def run(self, location=None):
3184
2620
b, relpath = Branch.open_containing(u'.')
3185
if location is None:
3187
location = b.get_old_bound_location()
3188
except errors.UpgradeRequired:
3189
raise errors.BzrCommandError('No location supplied. '
3190
'This format does not remember old locations.')
3192
if location is None:
3193
raise errors.BzrCommandError('No location supplied and no '
3194
'previous location known')
3195
2621
b_other = Branch.open(location)
3197
2623
b.bind(b_other)
3198
except errors.DivergedBranches:
3199
raise errors.BzrCommandError('These branches have diverged.'
3200
' Try merging, and then bind again.')
2624
except DivergedBranches:
2625
raise BzrCommandError('These branches have diverged.'
2626
' Try merging, and then bind again.')
3203
2629
class cmd_unbind(Command):
3204
"""Convert the current checkout into a regular branch.
2630
"""Unbind the current branch from its master branch.
3206
After unbinding, the local branch is considered independent and subsequent
3207
commits will be local only.
2632
After unbinding, the local branch is considered independent.
2633
All subsequent commits will be local.
3210
_see_also = ['checkouts', 'bind']
3211
2636
takes_args = []
3212
2637
takes_options = []
3215
2640
b, relpath = Branch.open_containing(u'.')
3216
2641
if not b.unbind():
3217
raise errors.BzrCommandError('Local branch is not bound')
2642
raise BzrCommandError('Local branch is not bound')
3220
2645
class cmd_uncommit(Command):
3326
class cmd_wait_until_signalled(Command):
3327
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
3329
This just prints a line to signal when it is ready, then blocks on stdin.
3335
sys.stdout.write("running\n")
3337
sys.stdin.readline()
3340
class cmd_serve(Command):
3341
"""Run the bzr server."""
3343
aliases = ['server']
3347
help='serve on stdin/out for use from inetd or sshd'),
3349
help='listen for connections on nominated port of the form '
3350
'[hostname:]portnumber. Passing 0 as the port number will '
3351
'result in a dynamically allocated port. Default port is '
3355
help='serve contents of directory',
3357
Option('allow-writes',
3358
help='By default the server is a readonly server. Supplying '
3359
'--allow-writes enables write access to the contents of '
3360
'the served directory and below. '
3364
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3365
from bzrlib.smart import medium, server
3366
from bzrlib.transport import get_transport
3367
from bzrlib.transport.chroot import ChrootServer
3368
from bzrlib.transport.remote import BZR_DEFAULT_PORT, BZR_DEFAULT_INTERFACE
3369
if directory is None:
3370
directory = os.getcwd()
3371
url = urlutils.local_path_to_url(directory)
3372
if not allow_writes:
3373
url = 'readonly+' + url
3374
chroot_server = ChrootServer(get_transport(url))
3375
chroot_server.setUp()
3376
t = get_transport(chroot_server.get_url())
3378
smart_server = medium.SmartServerPipeStreamMedium(
3379
sys.stdin, sys.stdout, t)
3381
host = BZR_DEFAULT_INTERFACE
3383
port = BZR_DEFAULT_PORT
3386
host, port = port.split(':')
3388
smart_server = server.SmartTCPServer(t, host=host, port=port)
3389
print 'listening on port: ', smart_server.port
3391
# for the duration of this server, no UI output is permitted.
3392
# note that this may cause problems with blackbox tests. This should
3393
# be changed with care though, as we dont want to use bandwidth sending
3394
# progress over stderr to smart server clients!
3395
old_factory = ui.ui_factory
3397
ui.ui_factory = ui.SilentUIFactory()
3398
smart_server.serve()
3400
ui.ui_factory = old_factory
3403
class cmd_join(Command):
3404
"""Combine a subtree into its containing tree.
3406
This command is for experimental use only. It requires the target tree
3407
to be in dirstate-with-subtree format, which cannot be converted into
3410
The TREE argument should be an independent tree, inside another tree, but
3411
not part of it. (Such trees can be produced by "bzr split", but also by
3412
running "bzr branch" with the target inside a tree.)
3414
The result is a combined tree, with the subtree no longer an independant
3415
part. This is marked as a merge of the subtree into the containing tree,
3416
and all history is preserved.
3418
If --reference is specified, the subtree retains its independence. It can
3419
be branched by itself, and can be part of multiple projects at the same
3420
time. But operations performed in the containing tree, such as commit
3421
and merge, will recurse into the subtree.
3424
_see_also = ['split']
3425
takes_args = ['tree']
3426
takes_options = [Option('reference', 'join by reference')]
3429
def run(self, tree, reference=False):
3430
sub_tree = WorkingTree.open(tree)
3431
parent_dir = osutils.dirname(sub_tree.basedir)
3432
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3433
repo = containing_tree.branch.repository
3434
if not repo.supports_rich_root():
3435
raise errors.BzrCommandError(
3436
"Can't join trees because %s doesn't support rich root data.\n"
3437
"You can use bzr upgrade on the repository."
3441
containing_tree.add_reference(sub_tree)
3442
except errors.BadReferenceTarget, e:
3443
# XXX: Would be better to just raise a nicely printable
3444
# exception from the real origin. Also below. mbp 20070306
3445
raise errors.BzrCommandError("Cannot join %s. %s" %
3449
containing_tree.subsume(sub_tree)
3450
except errors.BadSubsumeSource, e:
3451
raise errors.BzrCommandError("Cannot join %s. %s" %
3455
class cmd_split(Command):
3456
"""Split a tree into two trees.
3458
This command is for experimental use only. It requires the target tree
3459
to be in dirstate-with-subtree format, which cannot be converted into
3462
The TREE argument should be a subdirectory of a working tree. That
3463
subdirectory will be converted into an independent tree, with its own
3464
branch. Commits in the top-level tree will not apply to the new subtree.
3465
If you want that behavior, do "bzr join --reference TREE".
3468
_see_also = ['join']
3469
takes_args = ['tree']
3473
def run(self, tree):
3474
containing_tree, subdir = WorkingTree.open_containing(tree)
3475
sub_id = containing_tree.path2id(subdir)
3477
raise errors.NotVersionedError(subdir)
3479
containing_tree.extract(sub_id)
3480
except errors.RootNotRich:
3481
raise errors.UpgradeRequired(containing_tree.branch.base)
3485
class cmd_merge_directive(Command):
3486
"""Generate a merge directive for auto-merge tools.
3488
A directive requests a merge to be performed, and also provides all the
3489
information necessary to do so. This means it must either include a
3490
revision bundle, or the location of a branch containing the desired
3493
A submit branch (the location to merge into) must be supplied the first
3494
time the command is issued. After it has been supplied once, it will
3495
be remembered as the default.
3497
A public branch is optional if a revision bundle is supplied, but required
3498
if --diff or --plain is specified. It will be remembered as the default
3499
after the first use.
3502
takes_args = ['submit_branch?', 'public_branch?']
3505
RegistryOption.from_kwargs('patch-type',
3506
'The type of patch to include in the directive',
3507
title='Patch type', value_switches=True, enum_switch=False,
3508
bundle='Bazaar revision bundle (default)',
3509
diff='Normal unified diff',
3510
plain='No patch, just directive'),
3511
Option('sign', help='GPG-sign the directive'), 'revision',
3512
Option('mail-to', type=str,
3513
help='Instead of printing the directive, email to this address'),
3514
Option('message', type=str, short_name='m',
3515
help='Message to use when committing this merge')
3518
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3519
sign=False, revision=None, mail_to=None, message=None):
3520
if patch_type == 'plain':
3522
branch = Branch.open('.')
3523
stored_submit_branch = branch.get_submit_branch()
3524
if submit_branch is None:
3525
submit_branch = stored_submit_branch
3527
if stored_submit_branch is None:
3528
branch.set_submit_branch(submit_branch)
3529
if submit_branch is None:
3530
submit_branch = branch.get_parent()
3531
if submit_branch is None:
3532
raise errors.BzrCommandError('No submit branch specified or known')
3534
stored_public_branch = branch.get_public_branch()
3535
if public_branch is None:
3536
public_branch = stored_public_branch
3537
elif stored_public_branch is None:
3538
branch.set_public_branch(public_branch)
3539
if patch_type != "bundle" and public_branch is None:
3540
raise errors.BzrCommandError('No public branch specified or'
3542
if revision is not None:
3543
if len(revision) != 1:
3544
raise errors.BzrCommandError('bzr merge-directive takes '
3545
'exactly one revision identifier')
3547
revision_id = revision[0].in_history(branch).rev_id
3549
revision_id = branch.last_revision()
3550
directive = merge_directive.MergeDirective.from_objects(
3551
branch.repository, revision_id, time.time(),
3552
osutils.local_time_offset(), submit_branch,
3553
public_branch=public_branch, patch_type=patch_type,
3557
self.outf.write(directive.to_signed(branch))
3559
self.outf.writelines(directive.to_lines())
3561
message = directive.to_email(mail_to, branch, sign)
3563
server = branch.get_config().get_user_option('smtp_server')
3565
server = 'localhost'
3567
s.sendmail(message['From'], message['To'], message.as_string())
3570
class cmd_tag(Command):
3571
"""Create a tag naming a revision.
3573
Tags give human-meaningful names to revisions. Commands that take a -r
3574
(--revision) option can be given -rtag:X, where X is any previously
3577
Tags are stored in the branch. Tags are copied from one branch to another
3578
along when you branch, push, pull or merge.
3580
It is an error to give a tag name that already exists unless you pass
3581
--force, in which case the tag is moved to point to the new revision.
3584
_see_also = ['commit', 'tags']
3585
takes_args = ['tag_name']
3588
help='Delete this tag rather than placing it.',
3591
help='Branch in which to place the tag.',
3596
help='Replace existing tags',
3601
def run(self, tag_name,
3607
branch, relpath = Branch.open_containing(directory)
3611
branch.tags.delete_tag(tag_name)
3612
self.outf.write('Deleted tag %s.\n' % tag_name)
3615
if len(revision) != 1:
3616
raise errors.BzrCommandError(
3617
"Tags can only be placed on a single revision, "
3619
revision_id = revision[0].in_history(branch).rev_id
3621
revision_id = branch.last_revision()
3622
if (not force) and branch.tags.has_tag(tag_name):
3623
raise errors.TagAlreadyExists(tag_name)
3624
branch.tags.set_tag(tag_name, revision_id)
3625
self.outf.write('Created tag %s.\n' % tag_name)
3630
class cmd_tags(Command):
3633
This tag shows a table of tag names and the revisions they reference.
3639
help='Branch whose tags should be displayed',
3649
branch, relpath = Branch.open_containing(directory)
3650
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3651
self.outf.write('%-20s %s\n' % (tag_name, target))
3654
2751
# command-line interpretation helper for merge-related commands
3655
def _merge_helper(other_revision, base_revision,
3656
check_clean=True, ignore_zero=False,
3657
this_dir=None, backup_files=False,
3659
file_list=None, show_base=False, reprocess=False,
3662
change_reporter=None,
2752
def merge(other_revision, base_revision,
2753
check_clean=True, ignore_zero=False,
2754
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2755
file_list=None, show_base=False, reprocess=False,
2756
pb=DummyProgress()):
3664
2757
"""Merge changes into a tree.
3688
2781
clients might prefer to call merge.merge_inner(), which has less magic
3691
# Loading it late, so that we don't always have to import bzrlib.merge
3692
if merge_type is None:
3693
merge_type = _mod_merge.Merge3Merger
2784
from bzrlib.merge import Merger
3694
2785
if this_dir is None:
3695
2786
this_dir = u'.'
3696
2787
this_tree = WorkingTree.open_containing(this_dir)[0]
3697
if show_base and not merge_type is _mod_merge.Merge3Merger:
3698
raise errors.BzrCommandError("Show-base is not supported for this merge"
3699
" type. %s" % merge_type)
2788
if show_base and not merge_type is Merge3Merger:
2789
raise BzrCommandError("Show-base is not supported for this merge"
2790
" type. %s" % merge_type)
3700
2791
if reprocess and not merge_type.supports_reprocess:
3701
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3702
" type %s." % merge_type)
2792
raise BzrCommandError("Conflict reduction is not supported for merge"
2793
" type %s." % merge_type)
3703
2794
if reprocess and show_base:
3704
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3705
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3706
# only want to take out a lock_tree_write() if we don't have to pull
3707
# any ancestry. But merge might fetch ancestry in the middle, in
3708
# which case we would need a lock_write().
3709
# Because we cannot upgrade locks, for now we live with the fact that
3710
# the tree will be locked multiple times during a merge. (Maybe
3711
# read-only some of the time, but it means things will get read
2795
raise BzrCommandError("Cannot do conflict reduction and show base.")
3714
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3715
pb=pb, change_reporter=change_reporter)
2797
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
3716
2798
merger.pp = ProgressPhase("Merge phase", 5, pb)
3717
2799
merger.pp.next_phase()
3718
2800
merger.check_basis(check_clean)
3719
if other_rev_id is not None:
3720
merger.set_other_revision(other_rev_id, this_tree.branch)
3722
merger.set_other(other_revision)
2801
merger.set_other(other_revision)
3723
2802
merger.pp.next_phase()
3724
2803
merger.set_base(base_revision)
3725
2804
if merger.base_rev_id == merger.other_rev_id:
3726
2805
note('Nothing to do.')
3728
if file_list is None:
3729
if pull and merger.base_rev_id == merger.this_rev_id:
3730
# FIXME: deduplicate with pull
3731
result = merger.this_tree.pull(merger.this_branch,
3732
False, merger.other_rev_id)
3733
if result.old_revid == result.new_revid:
3734
note('No revisions to pull.')
3736
note('Now on revision %d.' % result.new_revno)
3738
2807
merger.backup_files = backup_files
3739
2808
merger.merge_type = merge_type
3740
2809
merger.set_interesting_files(file_list)