566
425
location can be accessed.
569
_see_also = ['push', 'update', 'status-flags']
570
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
572
help='Branch to pull into, '
573
'rather than the one containing the working directory.',
428
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
578
429
takes_args = ['location?']
579
430
encoding_type = 'replace'
581
def run(self, location=None, remember=False, overwrite=False,
582
revision=None, verbose=False,
584
from bzrlib.tag import _merge_tags_if_possible
432
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
585
433
# FIXME: too much stuff is in the command class
588
if directory is None:
591
tree_to = WorkingTree.open_containing(directory)[0]
435
tree_to = WorkingTree.open_containing(u'.')[0]
592
436
branch_to = tree_to.branch
593
except errors.NoWorkingTree:
437
except NoWorkingTree:
595
branch_to = Branch.open_containing(directory)[0]
439
branch_to = Branch.open_containing(u'.')[0]
597
442
if location is not None:
598
mergeable, location_transport = _get_bundle_helper(location)
444
reader = bundle.read_bundle_from_url(location)
446
pass # Continue on considering this url a Branch
600
448
stored_loc = branch_to.get_parent()
601
449
if location is None:
602
450
if stored_loc is None:
603
raise errors.BzrCommandError("No pull location known or"
451
raise BzrCommandError("No pull location known or specified.")
606
453
display_url = urlutils.unescape_for_display(stored_loc,
607
454
self.outf.encoding)
608
455
self.outf.write("Using saved location: %s\n" % display_url)
609
456
location = stored_loc
610
location_transport = transport.get_transport(location)
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
mergeable.install_revisions(branch_to.repository)
617
base_revision_id, revision_id, verified = \
618
mergeable.get_merge_request(branch_to.repository)
459
if reader is not None:
460
install_bundle(branch_to.repository, reader)
619
461
branch_from = branch_to
621
branch_from = Branch.open_from_transport(location_transport)
463
branch_from = Branch.open(location)
623
465
if branch_to.get_parent() is None or remember:
624
466
branch_to.set_parent(branch_from.base)
626
if revision is not None:
627
if len(revision) == 1:
628
revision_id = revision[0].in_history(branch_from).rev_id
630
raise errors.BzrCommandError(
631
'bzr pull --revision takes one value.')
470
if reader is not None:
471
rev_id = reader.target
472
elif len(revision) == 1:
473
rev_id = revision[0].in_history(branch_from).rev_id
475
raise BzrCommandError('bzr pull --revision takes one value.')
634
old_rh = branch_to.revision_history()
477
old_rh = branch_to.revision_history()
635
478
if tree_to is not None:
636
result = tree_to.pull(branch_from, overwrite, revision_id,
637
delta._ChangeReporter(unversioned_filter=tree_to.is_ignored))
479
count = tree_to.pull(branch_from, overwrite, rev_id)
639
result = branch_to.pull(branch_from, overwrite, revision_id)
481
count = branch_to.pull(branch_from, overwrite, rev_id)
482
note('%d revision(s) pulled.' % (count,))
641
result.report(self.outf)
643
from bzrlib.log import show_changed_revisions
644
485
new_rh = branch_to.revision_history()
645
show_changed_revisions(branch_to, old_rh, new_rh,
488
from bzrlib.log import show_changed_revisions
489
show_changed_revisions(branch_to, old_rh, new_rh,
649
493
class cmd_push(Command):
712
540
location = stored_loc
714
542
to_transport = transport.get_transport(location)
543
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?
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:
729
repository_to = dir_to.find_repository()
730
except errors.NoRepositoryPresent:
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)
733
# Found a branch, so we must have found a repository
734
repository_to = br_to.repository
739
# The destination doesn't exist; create it.
740
# XXX: Refactor the create_prefix/no_create_prefix code into a
741
# common helper function
743
to_transport.mkdir('.')
744
except errors.FileExists:
745
if not use_existing_dir:
746
raise errors.BzrCommandError("Target directory %s"
747
" already exists, but does not have a valid .bzr"
748
" directory. Supply --use-existing-dir to push"
749
" there anyway." % location)
750
except errors.NoSuchFile:
751
if not create_prefix:
752
raise errors.BzrCommandError("Parent directory of %s"
754
"\nYou may supply --create-prefix to create all"
755
" 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,
561
current = to_transport.base
562
needed = [(to_transport, to_transport.relpath(location_url))]
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 "
575
dir_to = br_from.bzrdir.clone(location_url,
763
576
revision_id=br_from.last_revision())
764
577
br_to = dir_to.open_branch()
765
# TODO: Some more useful message about what was copied
766
note('Created new branch.')
578
count = len(br_to.revision_history())
767
579
# We successfully created the target, remember it
768
580
if br_from.get_push_location() is None or remember:
769
581
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
789
583
# We were able to connect to the remote location, so remember it
790
584
# we don't need to successfully push because of possible divergence.
791
585
if br_from.get_push_location() is None or remember:
792
586
br_from.set_push_location(br_to.base)
794
old_rh = br_to.revision_history()
587
old_rh = br_to.revision_history()
797
590
tree_to = dir_to.open_workingtree()
798
591
except errors.NotLocalUrl:
799
warning("This transport does not update the working "
800
"tree of: %s. See 'bzr help working-trees' for "
801
"more information." % br_to.base)
802
push_result = br_from.push(br_to, overwrite)
803
except errors.NoWorkingTree:
804
push_result = br_from.push(br_to, overwrite)
592
warning('This transport does not update the working '
593
'tree of: %s' % (br_to.base,))
594
count = br_to.pull(br_from, overwrite)
595
except NoWorkingTree:
596
count = br_to.pull(br_from, overwrite)
808
push_result = br_from.push(tree_to.branch, overwrite)
812
except errors.DivergedBranches:
813
raise errors.BzrCommandError('These branches have diverged.'
814
' Try using "merge" and then "push".')
815
if push_result is not None:
816
push_result.report(self.outf)
598
count = tree_to.pull(br_from, overwrite)
599
except DivergedBranches:
600
raise BzrCommandError("These branches have diverged."
601
" Try a merge then push with overwrite.")
602
note('%d revision(s) pushed.' % (count,))
818
605
new_rh = br_to.revision_history()
819
606
if old_rh != new_rh:
820
607
# Something changed
821
608
from bzrlib.log import show_changed_revisions
822
609
show_changed_revisions(br_to, old_rh, new_rh,
823
610
to_file=self.outf)
825
# we probably did a clone rather than a push, so a message was
830
613
class cmd_branch(Command):
907
700
If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
908
701
be used. In other words, "checkout ../foo/bar" will attempt to create ./bar.
909
If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
910
is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
911
identifier, if any. For example, "checkout lp:foo-bar" will attempt to
914
703
To retrieve the branch as of a particular revision, supply the --revision
915
704
parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
916
705
out of date [so you cannot commit] but it may be useful (i.e. to examine old
708
--basis is to speed up checking out from remote branches. When specified, it
709
uses the inventory and file contents from the basis branch in preference to the
710
branch being checked out.
920
_see_also = ['checkouts', 'branch']
921
712
takes_args = ['branch_location?', 'to_location?']
922
takes_options = ['revision',
713
takes_options = ['revision', # , 'basis']
923
714
Option('lightweight',
924
help="Perform a lightweight checkout. Lightweight "
715
help="perform a lightweight checkout. Lightweight "
925
716
"checkouts depend on access to the branch for "
926
"every operation. Normal checkouts can perform "
717
"every operation. Normal checkouts can perform "
927
718
"common operations like diff and status without "
928
719
"such access, and also support local commits."
933
def run(self, branch_location=None, to_location=None, revision=None,
724
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
934
725
lightweight=False):
935
726
if revision is None:
936
727
revision = [None]
937
728
elif len(revision) > 1:
938
raise errors.BzrCommandError(
729
raise BzrCommandError(
939
730
'bzr checkout --revision takes exactly 1 revision value')
940
731
if branch_location is None:
941
732
branch_location = osutils.getcwd()
942
733
to_location = branch_location
943
734
source = Branch.open(branch_location)
944
735
if len(revision) == 1 and revision[0] is not None:
945
revision_id = _mod_revision.ensure_null(
946
revision[0].in_history(source)[1])
736
revision_id = revision[0].in_history(source)[1]
948
738
revision_id = None
949
739
if to_location is None:
950
to_location = urlutils.derive_to_location(branch_location)
740
to_location = os.path.basename(branch_location.rstrip("/\\"))
951
741
# if the source and to_location are the same,
952
742
# and there is no working tree,
953
743
# then reconstitute a branch
954
if (osutils.abspath(to_location) ==
744
if (osutils.abspath(to_location) ==
955
745
osutils.abspath(branch_location)):
957
747
source.bzrdir.open_workingtree()
958
748
except errors.NoWorkingTree:
959
source.bzrdir.create_workingtree(revision_id)
749
source.bzrdir.create_workingtree()
962
752
os.mkdir(to_location)
963
753
except OSError, e:
964
754
if e.errno == errno.EEXIST:
965
raise errors.BzrCommandError('Target directory "%s" already'
966
' exists.' % to_location)
755
raise BzrCommandError('Target directory "%s" already'
756
' exists.' % to_location)
967
757
if e.errno == errno.ENOENT:
968
raise errors.BzrCommandError('Parent of "%s" does not exist.'
758
raise BzrCommandError('Parent of "%s" does not exist.' %
972
source.create_checkout(to_location, revision_id, lightweight)
762
old_format = bzrdir.BzrDirFormat.get_default_format()
763
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
766
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
767
branch.BranchReferenceFormat().initialize(checkout, source)
769
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
770
to_location, force_new_tree=False)
771
checkout = checkout_branch.bzrdir
772
checkout_branch.bind(source)
773
if revision_id is not None:
774
rh = checkout_branch.revision_history()
775
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
776
checkout.create_workingtree(revision_id)
778
bzrdir.BzrDirFormat.set_default_format(old_format)
975
781
class cmd_renames(Command):
1285
1033
# Just using os.mkdir, since I don't
1286
1034
# believe that we want to create a bunch of
1287
1035
# locations if the user supplies an extended path
1289
to_transport.ensure_base()
1290
except errors.NoSuchFile:
1291
if not create_prefix:
1292
raise errors.BzrCommandError("Parent directory of %s"
1294
"\nYou may supply --create-prefix to create all"
1295
" leading parent directories."
1297
_create_prefix(to_transport)
1300
existing_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1301
except errors.NotBranchError:
1036
# TODO: create-prefix
1038
to_transport.mkdir('.')
1039
except errors.FileExists:
1043
existing_bzrdir = bzrdir.BzrDir.open(location)
1044
except NotBranchError:
1302
1045
# really a NotBzrDir error...
1303
create_branch = bzrdir.BzrDir.create_branch_convenience
1304
branch = create_branch(to_transport.base, format=format,
1305
possible_transports=[to_transport])
1046
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1307
from bzrlib.transport.local import LocalTransport
1308
1048
if existing_bzrdir.has_branch():
1309
1049
if (isinstance(to_transport, LocalTransport)
1310
1050
and not existing_bzrdir.has_workingtree()):
1311
1051
raise errors.BranchExistsWithoutWorkingTree(location)
1312
1052
raise errors.AlreadyBranchError(location)
1314
branch = existing_bzrdir.create_branch()
1054
existing_bzrdir.create_branch()
1315
1055
existing_bzrdir.create_workingtree()
1316
if append_revisions_only:
1318
branch.set_append_revisions_only(True)
1319
except errors.UpgradeRequired:
1320
raise errors.BzrCommandError('This branch format cannot be set'
1321
' to append-revisions-only. Try --experimental-branch6')
1324
1058
class cmd_init_repository(Command):
1325
1059
"""Create a shared repository to hold branches.
1327
New branches created under the repository directory will store their
1328
revisions in the repository, not in the branch directory.
1330
If the --no-trees option is used then the branches in the repository
1331
will not have working trees by default.
1061
New branches created under the repository directory will store their revisions
1062
in the repository, not in the branch directory, if the branch format supports
1334
bzr init-repo --no-trees repo
1335
1067
bzr init repo/trunk
1336
1068
bzr checkout --lightweight repo/trunk trunk-checkout
1337
1069
cd trunk-checkout
1338
1070
(add files here)
1340
See 'bzr help repositories' for more information.
1343
_see_also = ['init', 'branch', 'checkout']
1344
takes_args = ["location"]
1345
takes_options = [RegistryOption('format',
1346
help='Specify a format for this repository. See'
1347
' "bzr help formats" for details.',
1348
registry=bzrdir.format_registry,
1349
converter=bzrdir.format_registry.make_bzrdir,
1350
value_switches=True, title='Repository format'),
1352
help='Branches in the repository will default to'
1353
' 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'
1355
1082
aliases = ["init-repo"]
1357
def run(self, location, format=None, no_trees=False):
1083
def run(self, location, format=None, trees=False):
1358
1084
if format is None:
1359
format = bzrdir.format_registry.make_bzrdir('default')
1085
format = get_format_type('default')
1361
1087
if location is None:
1364
1090
to_transport = transport.get_transport(location)
1365
to_transport.ensure_base()
1092
to_transport.mkdir('.')
1093
except errors.FileExists:
1367
1096
newdir = format.initialize_on_transport(to_transport)
1368
1097
repo = newdir.create_repository(shared=True)
1369
repo.set_make_working_trees(not no_trees)
1098
repo.set_make_working_trees(trees)
1372
1101
class cmd_diff(Command):
1739
1415
class cmd_ls(Command):
1740
1416
"""List files in a tree.
1743
_see_also = ['status', 'cat']
1744
takes_args = ['path?']
1745
1418
# TODO: Take a revision or remote path and list that tree instead.
1749
Option('non-recursive',
1750
help='Don\'t recurse into subdirectories.'),
1752
help='Print paths relative to the root of the branch.'),
1753
Option('unknown', help='Print unknown files.'),
1754
Option('versioned', help='Print versioned files.'),
1755
Option('ignored', help='Print ignored files.'),
1757
help='Write an ascii NUL (\\0) separator '
1758
'between files rather than a newline.'),
1760
help='List entries of a particular kind: file, directory, symlink.',
1420
takes_options = ['verbose', 'revision',
1421
Option('non-recursive',
1422
help='don\'t recurse into sub-directories'),
1424
help='Print all paths from the root of the branch.'),
1425
Option('unknown', help='Print unknown files'),
1426
Option('versioned', help='Print versioned files'),
1427
Option('ignored', help='Print ignored files'),
1429
Option('null', help='Null separate the files'),
1764
1431
@display_command
1765
def run(self, revision=None, verbose=False,
1432
def run(self, revision=None, verbose=False,
1766
1433
non_recursive=False, from_root=False,
1767
1434
unknown=False, versioned=False, ignored=False,
1768
null=False, kind=None, show_ids=False, path=None):
1770
if kind and kind not in ('file', 'directory', 'symlink'):
1771
raise errors.BzrCommandError('invalid kind specified')
1773
1437
if verbose and null:
1774
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1438
raise BzrCommandError('Cannot set both --verbose and --null')
1775
1439
all = not (unknown or versioned or ignored)
1777
1441
selection = {'I':ignored, '?':unknown, 'V':versioned}
1784
raise errors.BzrCommandError('cannot specify both --from-root'
1788
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1443
tree, relpath = WorkingTree.open_containing(u'.')
1794
1448
if revision is not None:
1795
tree = branch.repository.revision_tree(
1796
revision[0].in_history(branch).rev_id)
1798
tree = branch.basis_tree()
1449
tree = tree.branch.repository.revision_tree(
1450
revision[0].in_history(tree.branch).rev_id)
1802
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1803
if fp.startswith(relpath):
1804
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1805
if non_recursive and '/' in fp:
1807
if not all and not selection[fc]:
1809
if kind is not None and fkind != kind:
1812
kindch = entry.kind_character()
1813
outstring = '%-8s %s%s' % (fc, fp, kindch)
1814
if show_ids and fid is not None:
1815
outstring = "%-50s %s" % (outstring, fid)
1816
self.outf.write(outstring + '\n')
1818
self.outf.write(fp + '\0')
1821
self.outf.write(fid)
1822
self.outf.write('\0')
1830
self.outf.write('%-50s %s\n' % (fp, my_id))
1832
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')
1837
1469
class cmd_unknowns(Command):
1838
"""List unknown files.
1470
"""List unknown files."""
1844
1471
@display_command
1846
1473
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2000
1597
tgz .tar.gz, .tgz
2003
takes_args = ['dest', 'branch?']
2006
help="Type of file to export to.",
2011
help="Name of the root directory inside the exported file."),
2013
def run(self, dest, branch=None, revision=None, format=None, root=None):
1600
takes_args = ['dest']
1601
takes_options = ['revision', 'format', 'root']
1602
def run(self, dest, revision=None, format=None, root=None):
2014
1603
from bzrlib.export import export
2017
tree = WorkingTree.open_containing(u'.')[0]
2020
b = Branch.open(branch)
1604
tree = WorkingTree.open_containing(u'.')[0]
2022
1606
if revision is None:
2023
1607
# should be tree.last_revision FIXME
2024
1608
rev_id = b.last_revision()
2026
1610
if len(revision) != 1:
2027
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1611
raise BzrError('bzr export --revision takes exactly 1 argument')
2028
1612
rev_id = revision[0].in_history(b).rev_id
2029
1613
t = b.repository.revision_tree(rev_id)
2031
1615
export(t, dest, format, root)
2032
1616
except errors.NoSuchExportFormat, e:
2033
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1617
raise BzrCommandError('Unsupported export format: %s' % e.format)
2036
1620
class cmd_cat(Command):
2037
"""Write the contents of a file as of a given revision to standard output.
2039
If no revision is nominated, the last revision is used.
2041
Note: Take care to redirect standard output when using this command on a
2047
Option('name-from-revision', help='The path name in the old tree.'),
1621
"""Write a file's text from a previous revision."""
1623
takes_options = ['revision']
2050
1624
takes_args = ['filename']
2051
encoding_type = 'exact'
2053
1626
@display_command
2054
def run(self, filename, revision=None, name_from_revision=False):
1627
def run(self, filename, revision=None):
2055
1628
if revision is not None and len(revision) != 1:
2056
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1629
raise BzrCommandError("bzr cat --revision takes exactly one number")
2061
tree, b, relpath = \
2062
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2063
except errors.NotBranchError:
1632
tree, relpath = WorkingTree.open_containing(filename)
1634
except NotBranchError:
2066
if revision is not None and revision[0].get_branch() is not None:
2067
b = Branch.open(revision[0].get_branch())
2068
1637
if tree is None:
2069
tree = b.basis_tree()
1638
b, relpath = Branch.open_containing(filename)
2070
1639
if revision is None:
2071
1640
revision_id = b.last_revision()
2073
1642
revision_id = revision[0].in_history(b).rev_id
2075
cur_file_id = tree.path2id(relpath)
2076
rev_tree = b.repository.revision_tree(revision_id)
2077
old_file_id = rev_tree.path2id(relpath)
2079
if name_from_revision:
2080
if old_file_id is None:
2081
raise errors.BzrCommandError("%r is not present in revision %s"
2082
% (filename, revision_id))
2084
rev_tree.print_file(old_file_id)
2085
elif cur_file_id is not None:
2086
rev_tree.print_file(cur_file_id)
2087
elif old_file_id is not None:
2088
rev_tree.print_file(old_file_id)
2090
raise errors.BzrCommandError("%r is not present in revision %s" %
2091
(filename, revision_id))
1643
b.print_file(relpath, revision_id)
2094
1646
class cmd_local_time_offset(Command):
2138
1675
# XXX: verbose currently does nothing
2140
_see_also = ['bugs', 'uncommit']
2141
1677
takes_args = ['selected*']
2143
Option('message', type=unicode,
2145
help="Description of the new revision."),
2148
help='Commit even if nothing has changed.'),
2149
Option('file', type=str,
2152
help='Take commit message from this file.'),
2154
help="Refuse to commit if there are unknown "
2155
"files in the working tree."),
2156
ListOption('fixes', type=str,
2157
help="Mark a bug as being fixed by this revision."),
2159
help="Perform a local commit in a bound "
2160
"branch. Local commits are not pushed to "
2161
"the master branch until a normal commit "
1678
takes_options = ['message', 'verbose',
1680
help='commit even if nothing has changed'),
1681
Option('file', type=str,
1683
help='file containing commit message'),
1685
help="refuse to commit if there are unknown "
1686
"files in the working tree."),
1688
help="perform a local only commit in a bound "
1689
"branch. Such commits are not pushed to "
1690
"the master branch until a normal commit "
2165
1694
aliases = ['ci', 'checkin']
2167
def _get_bug_fix_properties(self, fixes, branch):
2169
# Configure the properties for bug fixing attributes.
2170
for fixed_bug in fixes:
2171
tokens = fixed_bug.split(':')
2172
if len(tokens) != 2:
2173
raise errors.BzrCommandError(
2174
"Invalid bug %s. Must be in the form of 'tag:id'. "
2175
"Commit refused." % fixed_bug)
2176
tag, bug_id = tokens
2178
bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2179
except errors.UnknownBugTrackerAbbreviation:
2180
raise errors.BzrCommandError(
2181
'Unrecognized bug %s. Commit refused.' % fixed_bug)
2182
except errors.MalformedBugIdentifier:
2183
raise errors.BzrCommandError(
2184
"Invalid bug identifier for %s. Commit refused."
2186
properties.append('%s fixed' % bug_url)
2187
return '\n'.join(properties)
2189
1696
def run(self, message=None, file=None, verbose=True, selected_list=None,
2190
unchanged=False, strict=False, local=False, fixes=None):
1697
unchanged=False, strict=False, local=False):
2191
1698
from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2192
1699
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2193
1700
StrictCommitFailed)
2194
1701
from bzrlib.msgeditor import edit_commit_message, \
2195
1702
make_commit_message_template
1703
from tempfile import TemporaryFile
2197
1705
# TODO: Need a blackbox test for invoking the external editor; may be
2198
1706
# slightly problematic to run this cross-platform.
2200
1708
# TODO: do more checks that the commit will succeed before
2201
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
2205
1713
tree, selected_list = tree_files(selected_list)
2206
1714
if selected_list == ['']:
2207
1715
# workaround - commit of root of tree should be exactly the same
2209
1717
# selected-file merge commit is not done yet
2210
1718
selected_list = []
2212
bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2214
properties['bugs'] = bug_property
2216
1720
if local and not tree.branch.get_bound_location():
2217
1721
raise errors.LocalRequiresBoundBranch()
2219
def get_message(commit_obj):
2220
"""Callback to get commit message"""
2221
my_message = message
2222
if my_message is None and not file:
2223
template = make_commit_message_template(tree, selected_list)
2224
my_message = edit_commit_message(template)
2225
if my_message is None:
2226
raise errors.BzrCommandError("please specify a commit"
2227
" message with either --message or --file")
2228
elif my_message and file:
2229
raise errors.BzrCommandError(
2230
"please specify either --message or --file")
2232
my_message = codecs.open(file, 'rt',
2233
bzrlib.user_encoding).read()
2234
if my_message == "":
2235
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")
2239
1738
reporter = ReportCommitToLog()
2241
1740
reporter = NullCommitReporter()
2244
tree.commit(message_callback=get_message,
2245
specific_files=selected_list,
1743
tree.commit(message, specific_files=selected_list,
2246
1744
allow_pointless=unchanged, strict=strict, local=local,
2247
reporter=reporter, revprops=properties)
2248
1746
except PointlessCommit:
2249
1747
# FIXME: This should really happen before the file is read in;
2250
1748
# perhaps prepare the commit; get the message; then actually commit
2251
raise errors.BzrCommandError("no changes to commit."
2252
" use --unchanged to commit anyhow")
1749
raise BzrCommandError("no changes to commit."
1750
" use --unchanged to commit anyhow")
2253
1751
except ConflictsInTree:
2254
raise errors.BzrCommandError('Conflicts detected in working '
2255
'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.')
2257
1754
except StrictCommitFailed:
2258
raise errors.BzrCommandError("Commit refused because there are"
2259
" unknown files in the working tree.")
1755
raise BzrCommandError("Commit refused because there are unknown "
1756
"files in the working tree.")
2260
1757
except errors.BoundBranchOutOfDate, e:
2261
raise errors.BzrCommandError(str(e) + "\n"
2262
'To commit to master branch, run update and then commit.\n'
2263
'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.')
2267
1763
class cmd_check(Command):
2432
1924
return FakeNFSServer
2433
1925
msg = "No known transport type %s. Supported types are: sftp\n" %\
2435
raise errors.BzrCommandError(msg)
1927
raise BzrCommandError(msg)
2438
1930
takes_args = ['testspecs*']
2439
1931
takes_options = ['verbose',
2441
help='Stop when one test fails.',
1932
Option('one', help='stop when one test fails'),
1933
Option('keep-output',
1934
help='keep output directories when tests fail'),
2445
1936
help='Use a different transport by default '
2446
1937
'throughout the test suite.',
2447
1938
type=get_transport_type),
2449
help='Run the benchmarks rather than selftests.'),
1939
Option('benchmark', help='run the bzr bencharks.'),
2450
1940
Option('lsprof-timed',
2451
help='Generate lsprof output for benchmarked'
1941
help='generate lsprof output for benchmarked'
2452
1942
' sections of code.'),
2453
Option('cache-dir', type=str,
2454
help='Cache intermediate benchmark output in this '
2457
help='Run all tests, but run specified tests first.',
2461
help='List the tests instead of running them.'),
2462
Option('randomize', type=str, argname="SEED",
2463
help='Randomize the order of tests using the given'
2464
' seed or "now" for the current time.'),
2465
Option('exclude', type=str, argname="PATTERN",
2467
help='Exclude tests that match this regular'
2470
encoding_type = 'replace'
2472
1945
def run(self, testspecs_list=None, verbose=None, one=False,
2473
transport=None, benchmark=None,
2474
lsprof_timed=None, cache_dir=None,
2475
first=False, list_only=False,
2476
randomize=None, exclude=None):
1946
keep_output=False, transport=None, benchmark=None,
2477
1948
import bzrlib.ui
2478
1949
from bzrlib.tests import selftest
2479
1950
import bzrlib.benchmarks as benchmarks
2480
from bzrlib.benchmarks import tree_creator
2481
from bzrlib.version import show_version
2483
if cache_dir is not None:
2484
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2486
show_version(show_config=False, show_copyright=False)
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
1955
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1956
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2488
if testspecs_list is not None:
2489
pattern = '|'.join(testspecs_list)
2493
test_suite_factory = benchmarks.test_suite
2496
# TODO: should possibly lock the history file...
2497
benchfile = open(".perf_history", "at", buffering=1)
2499
test_suite_factory = None
1958
info('running tests...')
2504
result = selftest(verbose=verbose,
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
1973
result = selftest(verbose=verbose,
2505
1974
pattern=pattern,
2506
stop_on_failure=one,
1975
stop_on_failure=one,
1976
keep_output=keep_output,
2507
1977
transport=transport,
2508
1978
test_suite_factory=test_suite_factory,
2509
lsprof_timed=lsprof_timed,
2510
bench_history=benchfile,
2511
matching_tests_first=first,
2512
list_only=list_only,
2513
random_seed=randomize,
2514
exclude_pattern=exclude
1979
lsprof_timed=lsprof_timed)
1981
info('tests passed')
1983
info('tests failed')
1984
return int(not result)
2517
if benchfile is not None:
2520
info('tests passed')
2522
info('tests failed')
2523
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."
2526
2032
class cmd_version(Command):
2590
2100
default, use --remember. The value will only be saved if the remote
2591
2101
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.
2599
To merge the latest revision from bzr.dev:
2600
bzr merge ../bzr.dev
2105
To merge the latest revision from bzr.dev
2106
bzr merge ../bzr.dev
2602
To merge changes up to and including revision 82 from bzr.dev:
2603
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
2605
2111
To merge the changes introduced by 82, without previous changes:
2606
bzr merge -r 81..82 ../bzr.dev
2112
bzr merge -r 81..82 ../bzr.dev
2608
2114
merge refuses to run if there are any uncommitted changes, unless
2609
2115
--force is given.
2117
The following merge types are available:
2612
_see_also = ['update', 'remerge', 'status-flags']
2613
2119
takes_args = ['branch?']
2617
help='Merge even if the destination tree has uncommitted changes.'),
2621
Option('show-base', help="Show base revision text in "
2623
Option('uncommitted', help='Apply uncommitted changes'
2624
' from a working copy, instead of branch changes.'),
2625
Option('pull', help='If the destination is already'
2626
' completely merged into the source, pull from the'
2627
' source rather than merging. When this happens,'
2628
' you do not need to commit the result.'),
2630
help='Branch to merge into, '
2631
'rather than the one containing the working directory.',
2120
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
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()
2637
2129
def run(self, branch=None, revision=None, force=False, merge_type=None,
2638
show_base=False, reprocess=False, remember=False,
2639
uncommitted=False, pull=False,
2642
from bzrlib.tag import _merge_tags_if_possible
2130
show_base=False, reprocess=False, remember=False):
2643
2131
if merge_type is None:
2644
merge_type = _mod_merge.Merge3Merger
2646
if directory is None: directory = u'.'
2647
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2648
# inventory. Because merge is a mutating operation, it really
2649
# should be a lock_write() for the whole cmd_merge operation.
2650
# However, cmd_merge open's its own tree in _merge_helper, which
2651
# means if we lock here, the later lock_write() will always block.
2652
# Either the merge helper code should be updated to take a tree,
2653
# (What about tree.merge_from_branch?)
2654
tree = WorkingTree.open_containing(directory)[0]
2655
change_reporter = delta._ChangeReporter(
2656
unversioned_filter=tree.is_ignored)
2658
other_transport = None
2659
other_revision_id = None
2660
base_revision_id = None
2661
possible_transports = []
2132
merge_type = Merge3Merger
2134
tree = WorkingTree.open_containing(u'.')[0]
2663
2136
if branch is not None:
2664
mergeable, other_transport = _get_bundle_helper(branch)
2666
if revision is not None:
2667
raise errors.BzrCommandError(
2668
'Cannot use -r with merge directives or bundles')
2669
mergeable.install_revisions(tree.branch.repository)
2670
base_revision_id, other_revision_id, verified =\
2671
mergeable.get_merge_request(tree.branch.repository)
2672
if base_revision_id in tree.branch.repository.get_ancestry(
2673
tree.branch.last_revision(), topo_sorted=False):
2674
base_revision_id = None
2679
possible_transports.append(other_transport)
2681
if other_revision_id is None:
2682
verified = 'inapplicable'
2683
if revision is None \
2684
or len(revision) < 1 or revision[0].needs_branch():
2685
branch = self._get_remembered_parent(tree, branch,
2688
if revision is None or len(revision) < 1:
2691
other = [branch, None]
2694
other = [branch, -1]
2695
other_branch, path = Branch.open_containing(branch,
2696
possible_transports)
2699
raise errors.BzrCommandError('Cannot use --uncommitted and'
2700
' --revision at the same time.')
2701
branch = revision[0].get_branch() or branch
2702
if len(revision) == 1:
2704
other_branch, path = Branch.open_containing(
2705
branch, possible_transports)
2706
revno = revision[0].in_history(other_branch).revno
2707
other = [branch, revno]
2709
assert len(revision) == 2
2710
if None in revision:
2711
raise errors.BzrCommandError(
2712
"Merge doesn't permit empty revision specifier.")
2713
base_branch, path = Branch.open_containing(
2714
branch, possible_transports)
2715
branch1 = revision[1].get_branch() or branch
2716
other_branch, path1 = Branch.open_containing(
2717
branch1, possible_transports)
2718
if revision[0].get_branch() is not None:
2719
# then path was obtained from it, and is None.
2722
base = [branch, revision[0].in_history(base_branch).revno]
2724
revision[1].in_history(other_branch).revno]
2726
# Remember where we merge from
2727
if ((tree.branch.get_parent() is None or remember) and
2728
other_branch is not None):
2138
reader = bundle.read_bundle_from_url(branch)
2140
pass # Continue on considering this url a Branch
2142
conflicts = merge_bundle(reader, tree, not force, merge_type,
2143
reprocess, show_base)
2149
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2151
if revision is None or len(revision) < 1:
2153
other = [branch, -1]
2154
other_branch, path = Branch.open_containing(branch)
2156
if len(revision) == 1:
2158
other_branch, path = Branch.open_containing(branch)
2159
revno = revision[0].in_history(other_branch).revno
2160
other = [branch, revno]
2162
assert len(revision) == 2
2163
if None in revision:
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:
2729
2172
tree.branch.set_parent(other_branch.base)
2731
# pull tags now... it's a bit inconsistent to do it ahead of copying
2732
# the history but that's done inside the merge code
2733
if other_branch is not None:
2734
_merge_tags_if_possible(other_branch, tree.branch)
2737
2175
interesting_files = [path]
3425
class cmd_wait_until_signalled(Command):
3426
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
3428
This just prints a line to signal when it is ready, then blocks on stdin.
3434
sys.stdout.write("running\n")
3436
sys.stdin.readline()
3439
class cmd_serve(Command):
3440
"""Run the bzr server."""
3442
aliases = ['server']
3446
help='Serve on stdin/out for use from inetd or sshd.'),
3448
help='Listen for connections on nominated port of the form '
3449
'[hostname:]portnumber. Passing 0 as the port number will '
3450
'result in a dynamically allocated port. The default port is '
3454
help='Serve contents of this directory.',
3456
Option('allow-writes',
3457
help='By default the server is a readonly server. Supplying '
3458
'--allow-writes enables write access to the contents of '
3459
'the served directory and below.'
3463
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3464
from bzrlib.smart import medium, server
3465
from bzrlib.transport import get_transport
3466
from bzrlib.transport.chroot import ChrootServer
3467
from bzrlib.transport.remote import BZR_DEFAULT_PORT, BZR_DEFAULT_INTERFACE
3468
if directory is None:
3469
directory = os.getcwd()
3470
url = urlutils.local_path_to_url(directory)
3471
if not allow_writes:
3472
url = 'readonly+' + url
3473
chroot_server = ChrootServer(get_transport(url))
3474
chroot_server.setUp()
3475
t = get_transport(chroot_server.get_url())
3477
smart_server = medium.SmartServerPipeStreamMedium(
3478
sys.stdin, sys.stdout, t)
3480
host = BZR_DEFAULT_INTERFACE
3482
port = BZR_DEFAULT_PORT
3485
host, port = port.split(':')
3487
smart_server = server.SmartTCPServer(t, host=host, port=port)
3488
print 'listening on port: ', smart_server.port
3490
# for the duration of this server, no UI output is permitted.
3491
# note that this may cause problems with blackbox tests. This should
3492
# be changed with care though, as we dont want to use bandwidth sending
3493
# progress over stderr to smart server clients!
3494
old_factory = ui.ui_factory
3496
ui.ui_factory = ui.SilentUIFactory()
3497
smart_server.serve()
3499
ui.ui_factory = old_factory
3502
class cmd_join(Command):
3503
"""Combine a subtree into its containing tree.
3505
This command is for experimental use only. It requires the target tree
3506
to be in dirstate-with-subtree format, which cannot be converted into
3509
The TREE argument should be an independent tree, inside another tree, but
3510
not part of it. (Such trees can be produced by "bzr split", but also by
3511
running "bzr branch" with the target inside a tree.)
3513
The result is a combined tree, with the subtree no longer an independant
3514
part. This is marked as a merge of the subtree into the containing tree,
3515
and all history is preserved.
3517
If --reference is specified, the subtree retains its independence. It can
3518
be branched by itself, and can be part of multiple projects at the same
3519
time. But operations performed in the containing tree, such as commit
3520
and merge, will recurse into the subtree.
3523
_see_also = ['split']
3524
takes_args = ['tree']
3526
Option('reference', help='Join by reference.'),
3530
def run(self, tree, reference=False):
3531
sub_tree = WorkingTree.open(tree)
3532
parent_dir = osutils.dirname(sub_tree.basedir)
3533
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3534
repo = containing_tree.branch.repository
3535
if not repo.supports_rich_root():
3536
raise errors.BzrCommandError(
3537
"Can't join trees because %s doesn't support rich root data.\n"
3538
"You can use bzr upgrade on the repository."
3542
containing_tree.add_reference(sub_tree)
3543
except errors.BadReferenceTarget, e:
3544
# XXX: Would be better to just raise a nicely printable
3545
# exception from the real origin. Also below. mbp 20070306
3546
raise errors.BzrCommandError("Cannot join %s. %s" %
3550
containing_tree.subsume(sub_tree)
3551
except errors.BadSubsumeSource, e:
3552
raise errors.BzrCommandError("Cannot join %s. %s" %
3556
class cmd_split(Command):
3557
"""Split a tree into two trees.
3559
This command is for experimental use only. It requires the target tree
3560
to be in dirstate-with-subtree format, which cannot be converted into
3563
The TREE argument should be a subdirectory of a working tree. That
3564
subdirectory will be converted into an independent tree, with its own
3565
branch. Commits in the top-level tree will not apply to the new subtree.
3566
If you want that behavior, do "bzr join --reference TREE".
3569
_see_also = ['join']
3570
takes_args = ['tree']
3574
def run(self, tree):
3575
containing_tree, subdir = WorkingTree.open_containing(tree)
3576
sub_id = containing_tree.path2id(subdir)
3578
raise errors.NotVersionedError(subdir)
3580
containing_tree.extract(sub_id)
3581
except errors.RootNotRich:
3582
raise errors.UpgradeRequired(containing_tree.branch.base)
3586
class cmd_merge_directive(Command):
3587
"""Generate a merge directive for auto-merge tools.
3589
A directive requests a merge to be performed, and also provides all the
3590
information necessary to do so. This means it must either include a
3591
revision bundle, or the location of a branch containing the desired
3594
A submit branch (the location to merge into) must be supplied the first
3595
time the command is issued. After it has been supplied once, it will
3596
be remembered as the default.
3598
A public branch is optional if a revision bundle is supplied, but required
3599
if --diff or --plain is specified. It will be remembered as the default
3600
after the first use.
3603
takes_args = ['submit_branch?', 'public_branch?']
3607
_see_also = ['submit']
3610
RegistryOption.from_kwargs('patch-type',
3611
'The type of patch to include in the directive',
3613
value_switches=True,
3615
bundle='Bazaar revision bundle (default).',
3616
diff='Normal unified diff.',
3617
plain='No patch, just directive.'),
3618
Option('sign', help='GPG-sign the directive.'), 'revision',
3619
Option('mail-to', type=str,
3620
help='Instead of printing the directive, email to this address.'),
3621
Option('message', type=str, short_name='m',
3622
help='Message to use when committing this merge.')
3625
encoding_type = 'exact'
3627
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3628
sign=False, revision=None, mail_to=None, message=None):
3629
from bzrlib.revision import ensure_null, NULL_REVISION
3630
include_patch, include_bundle = {
3631
'plain': (False, False),
3632
'diff': (True, False),
3633
'bundle': (True, True),
3635
branch = Branch.open('.')
3636
stored_submit_branch = branch.get_submit_branch()
3637
if submit_branch is None:
3638
submit_branch = stored_submit_branch
3640
if stored_submit_branch is None:
3641
branch.set_submit_branch(submit_branch)
3642
if submit_branch is None:
3643
submit_branch = branch.get_parent()
3644
if submit_branch is None:
3645
raise errors.BzrCommandError('No submit branch specified or known')
3647
stored_public_branch = branch.get_public_branch()
3648
if public_branch is None:
3649
public_branch = stored_public_branch
3650
elif stored_public_branch is None:
3651
branch.set_public_branch(public_branch)
3652
if not include_bundle and public_branch is None:
3653
raise errors.BzrCommandError('No public branch specified or'
3655
base_revision_id = None
3656
if revision is not None:
3657
if len(revision) > 2:
3658
raise errors.BzrCommandError('bzr merge-directive takes '
3659
'at most two one revision identifiers')
3660
revision_id = revision[-1].in_history(branch).rev_id
3661
if len(revision) == 2:
3662
base_revision_id = revision[0].in_history(branch).rev_id
3663
base_revision_id = ensure_null(base_revision_id)
3665
revision_id = branch.last_revision()
3666
revision_id = ensure_null(revision_id)
3667
if revision_id == NULL_REVISION:
3668
raise errors.BzrCommandError('No revisions to bundle.')
3669
directive = merge_directive.MergeDirective2.from_objects(
3670
branch.repository, revision_id, time.time(),
3671
osutils.local_time_offset(), submit_branch,
3672
public_branch=public_branch, include_patch=include_patch,
3673
include_bundle=include_bundle, message=message,
3674
base_revision_id=base_revision_id)
3677
self.outf.write(directive.to_signed(branch))
3679
self.outf.writelines(directive.to_lines())
3681
message = directive.to_email(mail_to, branch, sign)
3682
s = SMTPConnection(branch.get_config())
3683
s.send_email(message)
3686
class cmd_submit(Command):
3687
"""Create a merge-directive for submiting changes.
3689
A merge directive provides many things needed for requesting merges:
3690
- A machine-readable description of the merge to perform
3691
- An optional patch that is a preview of the changes requested
3692
- An optional bundle of revision data, so that the changes can be applied
3693
directly from the merge directive, without retrieving data from a
3696
If --no-bundle is specified, then public_branch is needed (and must be
3697
up-to-date), so that the receiver can perform the merge using the
3698
public_branch. The public_branch is always included if known, so that
3699
people can check it later.
3701
The submit branch defaults to the parent, but can be overridden. Both
3702
submit branch and public branch will be remembered if supplied.
3704
If a public_branch is known for the submit_branch, that public submit
3705
branch is used in the merge instructions. This means that a local mirror
3706
can be used as your actual submit branch, once you have set public_branch
3710
encoding_type = 'exact'
3712
aliases = ['bundle', 'bundle-revisions']
3714
_see_also = ['merge']
3716
takes_args = ['submit_branch?', 'public_branch?']
3719
help='Do not include a bundle in the merge directive.'),
3720
Option('no-patch', help='Do not include a preview patch in the merge'
3723
help='Remember submit and public branch.'),
3725
help='Branch to generate the submission from, '
3726
'rather than the one containing the working directory.',
3729
Option('output', short_name='o', help='Write directive to this file.',
3734
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
3735
no_patch=False, revision=None, remember=False, output=None,
3737
from bzrlib.revision import ensure_null, NULL_REVISION
3741
outfile = open(output, 'wb')
3743
from_ = kwargs.get('from', '.')
3744
branch = Branch.open_containing(from_)[0]
3745
if remember and submit_branch is None:
3746
raise errors.BzrCommandError(
3747
'--remember requires a branch to be specified.')
3748
stored_submit_branch = branch.get_submit_branch()
3749
remembered_submit_branch = False
3750
if submit_branch is None:
3751
submit_branch = stored_submit_branch
3752
remembered_submit_branch = True
3754
if stored_submit_branch is None or remember:
3755
branch.set_submit_branch(submit_branch)
3756
if submit_branch is None:
3757
submit_branch = branch.get_parent()
3758
remembered_submit_branch = True
3759
if submit_branch is None:
3760
raise errors.BzrCommandError('No submit branch known or'
3762
if remembered_submit_branch:
3763
note('Using saved location: %s', submit_branch)
3765
stored_public_branch = branch.get_public_branch()
3766
if public_branch is None:
3767
public_branch = stored_public_branch
3768
elif stored_public_branch is None or remember:
3769
branch.set_public_branch(public_branch)
3770
if no_bundle and public_branch is None:
3771
raise errors.BzrCommandError('No public branch specified or'
3773
base_revision_id = None
3774
if revision is not None:
3775
if len(revision) > 2:
3776
raise errors.BzrCommandError('bzr submit takes '
3777
'at most two one revision identifiers')
3778
revision_id = revision[-1].in_history(branch).rev_id
3779
if len(revision) == 2:
3780
base_revision_id = revision[0].in_history(branch).rev_id
3781
base_revision_id = ensure_null(base_revision_id)
3783
revision_id = branch.last_revision()
3784
revision_id = ensure_null(revision_id)
3785
if revision_id == NULL_REVISION:
3786
raise errors.BzrCommandError('No revisions to submit.')
3787
directive = merge_directive.MergeDirective2.from_objects(
3788
branch.repository, revision_id, time.time(),
3789
osutils.local_time_offset(), submit_branch,
3790
public_branch=public_branch, include_patch=not no_patch,
3791
include_bundle=not no_bundle, message=None,
3792
base_revision_id=base_revision_id)
3793
outfile.writelines(directive.to_lines())
3795
if output is not None:
3798
class cmd_tag(Command):
3799
"""Create a tag naming a revision.
3801
Tags give human-meaningful names to revisions. Commands that take a -r
3802
(--revision) option can be given -rtag:X, where X is any previously
3805
Tags are stored in the branch. Tags are copied from one branch to another
3806
along when you branch, push, pull or merge.
3808
It is an error to give a tag name that already exists unless you pass
3809
--force, in which case the tag is moved to point to the new revision.
3812
_see_also = ['commit', 'tags']
3813
takes_args = ['tag_name']
3816
help='Delete this tag rather than placing it.',
3819
help='Branch in which to place the tag.',
3824
help='Replace existing tags.',
3829
def run(self, tag_name,
3835
branch, relpath = Branch.open_containing(directory)
3839
branch.tags.delete_tag(tag_name)
3840
self.outf.write('Deleted tag %s.\n' % tag_name)
3843
if len(revision) != 1:
3844
raise errors.BzrCommandError(
3845
"Tags can only be placed on a single revision, "
3847
revision_id = revision[0].in_history(branch).rev_id
3849
revision_id = branch.last_revision()
3850
if (not force) and branch.tags.has_tag(tag_name):
3851
raise errors.TagAlreadyExists(tag_name)
3852
branch.tags.set_tag(tag_name, revision_id)
3853
self.outf.write('Created tag %s.\n' % tag_name)
3858
class cmd_tags(Command):
3861
This tag shows a table of tag names and the revisions they reference.
3867
help='Branch whose tags should be displayed.',
3877
branch, relpath = Branch.open_containing(directory)
3878
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3879
self.outf.write('%-20s %s\n' % (tag_name, target))
3882
2751
# command-line interpretation helper for merge-related commands
3883
def _merge_helper(other_revision, base_revision,
3884
check_clean=True, ignore_zero=False,
3885
this_dir=None, backup_files=False,
3887
file_list=None, show_base=False, reprocess=False,
3890
change_reporter=None,
3891
other_rev_id=None, base_rev_id=None,
3892
possible_transports=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()):
3893
2757
"""Merge changes into a tree.