627
711
to_transport = transport.get_transport(location)
628
712
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
632
dir_to = bzrdir.BzrDir.open(location_url)
633
br_to = dir_to.open_branch()
634
except errors.NotBranchError:
636
to_transport = to_transport.clone('..')
637
if not create_prefix:
639
relurl = to_transport.relpath(location_url)
640
mutter('creating directory %s => %s', location_url, relurl)
641
to_transport.mkdir(relurl)
642
except errors.NoSuchFile:
643
raise errors.BzrCommandError("Parent directory of %s "
644
"does not exist." % location)
646
current = to_transport.base
647
needed = [(to_transport, to_transport.relpath(location_url))]
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
650
to_transport, relpath = needed[-1]
651
to_transport.mkdir(relpath)
653
except errors.NoSuchFile:
654
new_transport = to_transport.clone('..')
655
needed.append((new_transport,
656
new_transport.relpath(to_transport.base)))
657
if new_transport.base == to_transport.base:
658
raise errors.BzrCommandError("Could not create "
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.
660
780
dir_to = br_from.bzrdir.clone(location_url,
661
781
revision_id=br_from.last_revision())
662
782
br_to = dir_to.open_branch()
663
count = len(br_to.revision_history())
783
# TODO: Some more useful message about what was copied
784
note('Created new branch.')
664
785
# We successfully created the target, remember it
665
786
if br_from.get_push_location() is None or remember:
666
787
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
668
807
# We were able to connect to the remote location, so remember it
669
808
# we don't need to successfully push because of possible divergence.
670
809
if br_from.get_push_location() is None or remember:
946
1085
also new, they will also be removed.
948
1087
takes_args = ['file*']
949
takes_options = ['verbose', Option('new', help='remove newly-added files')]
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.')]
950
1098
aliases = ['rm']
951
1099
encoding_type = 'replace'
953
def run(self, file_list, verbose=False, new=False):
1101
def run(self, file_list, verbose=False, new=False,
1102
file_deletion_strategy='safe'):
954
1103
tree, file_list = tree_files(file_list)
956
if file_list is None:
957
raise errors.BzrCommandError('Specify one or more files to'
958
' remove, or use --new.')
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.')
960
1112
added = tree.changes_from(tree.basis_tree(),
961
1113
specific_files=file_list).added
962
1114
file_list = sorted([f[0] for f in added], reverse=True)
963
1115
if len(file_list) == 0:
964
1116
raise errors.BzrCommandError('No matching files.')
965
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1117
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1118
keep_files=file_deletion_strategy=='keep',
1119
force=file_deletion_strategy=='force')
968
1122
class cmd_file_id(Command):
1133
1303
raise errors.BranchExistsWithoutWorkingTree(location)
1134
1304
raise errors.AlreadyBranchError(location)
1136
existing_bzrdir.create_branch()
1306
branch = existing_bzrdir.create_branch()
1137
1307
existing_bzrdir.create_workingtree()
1308
if append_revisions_only:
1310
branch.set_append_revisions_only(True)
1311
except errors.UpgradeRequired:
1312
raise errors.BzrCommandError('This branch format cannot be set'
1313
' to append-revisions-only. Try --experimental-branch6')
1140
1316
class cmd_init_repository(Command):
1141
1317
"""Create a shared repository to hold branches.
1143
1319
New branches created under the repository directory will store their revisions
1144
in the repository, not in the branch directory, if the branch format supports
1320
in the repository, not in the branch directory.
1323
bzr init-repo --no-trees repo
1149
1324
bzr init repo/trunk
1150
1325
bzr checkout --lightweight repo/trunk trunk-checkout
1151
1326
cd trunk-checkout
1152
1327
(add files here)
1154
takes_args = ["location"]
1155
takes_options = [Option('format',
1156
help='Specify a format for this repository.'
1157
' Current formats are: default, knit,'
1158
' metaweave and weave. Default is knit;'
1159
' metaweave and weave are deprecated',
1160
type=get_format_type),
1162
help='Allows branches in repository to have'
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'),
1164
1342
aliases = ["init-repo"]
1165
def run(self, location, format=None, trees=False):
1344
def run(self, location, format=None, no_trees=False):
1166
1345
if format is None:
1167
format = get_format_type('default')
1346
format = bzrdir.format_registry.make_bzrdir('default')
1169
1348
if location is None:
1437
1636
dir, relpath = bzrdir.BzrDir.open_containing(location)
1438
1637
b = dir.open_branch()
1440
if revision is None:
1443
elif len(revision) == 1:
1444
rev1 = rev2 = revision[0].in_history(b).revno
1445
elif len(revision) == 2:
1446
if revision[1].get_branch() != revision[0].get_branch():
1447
# b is taken from revision[0].get_branch(), and
1448
# show_log will use its revision_history. Having
1449
# different branches will lead to weird behaviors.
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
1450
1666
raise errors.BzrCommandError(
1451
"Log doesn't accept two revisions in different branches.")
1452
if revision[0].spec is None:
1453
# missing begin-range means first revision
1456
rev1 = revision[0].in_history(b).revno
1458
if revision[1].spec is None:
1459
# missing end-range means last known revision
1462
rev2 = revision[1].in_history(b).revno
1464
raise errors.BzrCommandError('bzr log --revision takes one or two values.')
1466
# By this point, the revision numbers are converted to the +ve
1467
# form if they were supplied in the -ve form, so we can do
1468
# this comparison in relative safety
1470
(rev2, rev1) = (rev1, rev2)
1472
if (log_format is None):
1473
default = b.get_config().log_format()
1474
log_format = get_log_format(long=long, short=short, line=line,
1476
lf = log_formatter(log_format,
1479
show_timezone=timezone)
1485
direction=direction,
1486
start_revision=rev1,
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,
1491
1693
def get_log_format(long=False, short=False, line=False, default='long'):
1551
1754
selection = {'I':ignored, '?':unknown, 'V':versioned}
1553
tree, relpath = WorkingTree.open_containing(u'.')
1761
raise errors.BzrCommandError('cannot specify both --from-root'
1765
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1558
1771
if revision is not None:
1559
tree = tree.branch.repository.revision_tree(
1560
revision[0].in_history(tree.branch).rev_id)
1772
tree = branch.repository.revision_tree(
1773
revision[0].in_history(branch).rev_id)
1775
tree = branch.basis_tree()
1562
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1563
if fp.startswith(relpath):
1564
fp = fp[len(relpath):]
1565
if non_recursive and '/' in fp:
1567
if not all and not selection[fc]:
1569
if kind is not None and fkind != kind:
1572
kindch = entry.kind_character()
1573
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1575
self.outf.write(fp + '\0')
1578
self.outf.write(fp + '\n')
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')
1581
1814
class cmd_unknowns(Command):
1582
"""List unknown files."""
1815
"""List unknown files.
1583
1821
@display_command
1585
1823
for f in WorkingTree.open_containing(u'.')[0].unknowns():
2033
2338
@display_command
2034
2339
def printme(self, branch):
2038
2343
class cmd_selftest(Command):
2039
2344
"""Run internal test suite.
2041
This creates temporary test directories in the working directory,
2042
but not existing data is affected. These directories are deleted
2043
if the tests pass, or left behind to help in debugging if they
2044
fail and --keep-output is specified.
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
2046
If arguments are given, they are regular expressions that say
2047
which tests should run.
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.
2049
2374
If the global option '--no-plugins' is given, plugins are not loaded
2050
2375
before running the selftests. This has two effects: features provided or
2051
2376
modified by plugins will not be tested, and tests provided by plugins will
2055
2380
bzr selftest ignore
2381
run only tests relating to 'ignore'
2056
2382
bzr --no-plugins selftest -v
2383
disable plugins and list tests as they're run
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.
2058
# TODO: --list should give a list of all available tests
2060
2392
# NB: this is used from the class without creating an instance, which is
2061
2393
# why it does not have a self parameter.
2062
2394
def get_transport_type(typestring):
2220
2579
default, use --remember. The value will only be saved if the remote
2221
2580
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.
2225
To merge the latest revision from bzr.dev
2226
bzr merge ../bzr.dev
2588
To merge the latest revision from bzr.dev:
2589
bzr merge ../bzr.dev
2228
To merge changes up to and including revision 82 from bzr.dev
2229
bzr merge -r 82 ../bzr.dev
2591
To merge changes up to and including revision 82 from bzr.dev:
2592
bzr merge -r 82 ../bzr.dev
2231
2594
To merge the changes introduced by 82, without previous changes:
2232
bzr merge -r 81..82 ../bzr.dev
2595
bzr merge -r 81..82 ../bzr.dev
2234
2597
merge refuses to run if there are any uncommitted changes, unless
2235
2598
--force is given.
2237
The following merge types are available:
2601
_see_also = ['update', 'remerge']
2239
2602
takes_args = ['branch?']
2240
2603
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2241
Option('show-base', help="Show base revision text in "
2243
Option('uncommitted', help='Apply uncommitted changes'
2244
' from a working copy, instead of branch changes'),
2245
Option('pull', help='If the destination is already'
2246
' completely merged into the source, pull from the'
2247
' source rather than merging. When this happens,'
2248
' you do not need to commit the result.'),
2252
from inspect import getdoc
2253
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
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',
2255
2620
def run(self, branch=None, revision=None, force=False, merge_type=None,
2256
show_base=False, reprocess=False, remember=False,
2257
uncommitted=False, pull=False):
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
2258
2627
if merge_type is None:
2259
2628
merge_type = _mod_merge.Merge3Merger
2261
tree = WorkingTree.open_containing(u'.')[0]
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)
2263
2642
if branch is not None:
2265
reader = bundle.read_bundle_from_url(branch)
2644
mergeable = bundle.read_mergeable_from_url(
2266
2646
except errors.NotABundle:
2267
2647
pass # Continue on considering this url a Branch
2269
conflicts = merge_bundle(reader, tree, not force, merge_type,
2270
reprocess, show_base)
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)]
2276
2657
if revision is None \
2277
2658
or len(revision) < 1 or revision[0].needs_branch():
2958
3364
def run(self, port=None, inet=False, directory=None, allow_writes=False):
2959
from bzrlib.transport import smart
3365
from bzrlib.smart import medium, server
2960
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
2961
3369
if directory is None:
2962
3370
directory = os.getcwd()
2963
3371
url = urlutils.local_path_to_url(directory)
2964
3372
if not allow_writes:
2965
3373
url = 'readonly+' + url
2966
t = get_transport(url)
3374
chroot_server = ChrootServer(get_transport(url))
3375
chroot_server.setUp()
3376
t = get_transport(chroot_server.get_url())
2968
server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
2969
elif port is not None:
2971
host, port = port.split(':')
3378
smart_server = medium.SmartServerPipeStreamMedium(
3379
sys.stdin, sys.stdout, t)
3381
host = BZR_DEFAULT_INTERFACE
3383
port = BZR_DEFAULT_PORT
2974
server = smart.SmartTCPServer(t, host=host, port=int(port))
2975
print 'listening on port: ', server.port
3386
host, port = port.split(':')
3388
smart_server = server.SmartTCPServer(t, host=host, port=port)
3389
print 'listening on port: ', smart_server.port
2976
3390
sys.stdout.flush()
2978
raise errors.BzrCommandError("bzr serve requires one of --inet or --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))
2982
3654
# command-line interpretation helper for merge-related commands