2396
2806
The results of the merge are placed into the destination working
2397
2807
directory, where they can be reviewed (with bzr diff), tested, and then
2398
2808
committed to record the result of the merge.
2402
To merge the latest revision from bzr.dev
2403
bzr merge ../bzr.dev
2405
To merge changes up to and including revision 82 from bzr.dev
2406
bzr merge -r 82 ../bzr.dev
2408
To merge the changes introduced by 82, without previous changes:
2409
bzr merge -r 81..82 ../bzr.dev
2411
2810
merge refuses to run if there are any uncommitted changes, unless
2412
2811
--force is given.
2414
The following merge types are available:
2814
To merge the latest revision from bzr.dev::
2816
bzr merge ../bzr.dev
2818
To merge changes up to and including revision 82 from bzr.dev::
2820
bzr merge -r 82 ../bzr.dev
2822
To merge the changes introduced by 82, without previous changes::
2824
bzr merge -r 81..82 ../bzr.dev
2826
To apply a merge directive contained in in /tmp/merge:
2828
bzr merge /tmp/merge
2416
takes_args = ['branch?']
2417
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2831
encoding_type = 'exact'
2832
_see_also = ['update', 'remerge', 'status-flags']
2833
takes_args = ['location?']
2838
help='Merge even if the destination tree has uncommitted changes.'),
2418
2842
Option('show-base', help="Show base revision text in "
2420
2844
Option('uncommitted', help='Apply uncommitted changes'
2421
' from a working copy, instead of branch changes'),
2845
' from a working copy, instead of branch changes.'),
2422
2846
Option('pull', help='If the destination is already'
2423
2847
' completely merged into the source, pull from the'
2424
' source rather than merging. When this happens,'
2848
' source rather than merging. When this happens,'
2425
2849
' you do not need to commit the result.'),
2426
2850
Option('directory',
2427
help='branch to merge into, '
2428
'rather than the one containing the working directory',
2851
help='Branch to merge into, '
2852
'rather than the one containing the working directory.',
2856
Option('preview', help='Instead of merging, show a diff of the merge.')
2434
def run(self, branch=None, revision=None, force=False, merge_type=None,
2435
show_base=False, reprocess=False, remember=False,
2859
def run(self, location=None, revision=None, force=False,
2860
merge_type=None, show_base=False, reprocess=False, remember=False,
2436
2861
uncommitted=False, pull=False,
2437
2862
directory=None,
2439
2865
if merge_type is None:
2440
2866
merge_type = _mod_merge.Merge3Merger
2442
2868
if directory is None: directory = u'.'
2869
possible_transports = []
2871
allow_pending = True
2872
verified = 'inapplicable'
2443
2873
tree = WorkingTree.open_containing(directory)[0]
2444
change_reporter = delta.ChangeReporter(tree.inventory)
2446
if branch is not None:
2448
reader = bundle.read_bundle_from_url(branch)
2449
except errors.NotABundle:
2450
pass # Continue on considering this url a Branch
2452
conflicts = merge_bundle(reader, tree, not force, merge_type,
2453
reprocess, show_base, change_reporter)
2874
change_reporter = delta._ChangeReporter(
2875
unversioned_filter=tree.is_ignored)
2878
pb = ui.ui_factory.nested_progress_bar()
2879
cleanups.append(pb.finished)
2881
cleanups.append(tree.unlock)
2882
if location is not None:
2884
mergeable = bundle.read_mergeable_from_url(location,
2885
possible_transports=possible_transports)
2886
except errors.NotABundle:
2459
if revision is None \
2460
or len(revision) < 1 or revision[0].needs_branch():
2461
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2463
if revision is None or len(revision) < 1:
2466
other = [branch, None]
2469
other = [branch, -1]
2470
other_branch, path = Branch.open_containing(branch)
2473
raise errors.BzrCommandError('Cannot use --uncommitted and'
2474
' --revision at the same time.')
2475
branch = revision[0].get_branch() or branch
2476
if len(revision) == 1:
2478
other_branch, path = Branch.open_containing(branch)
2479
revno = revision[0].in_history(other_branch).revno
2480
other = [branch, revno]
2482
assert len(revision) == 2
2483
if None in revision:
2484
raise errors.BzrCommandError(
2485
"Merge doesn't permit empty revision specifier.")
2486
base_branch, path = Branch.open_containing(branch)
2487
branch1 = revision[1].get_branch() or branch
2488
other_branch, path1 = Branch.open_containing(branch1)
2489
if revision[0].get_branch() is not None:
2490
# then path was obtained from it, and is None.
2493
base = [branch, revision[0].in_history(base_branch).revno]
2494
other = [branch1, revision[1].in_history(other_branch).revno]
2496
if tree.branch.get_parent() is None or remember:
2497
tree.branch.set_parent(other_branch.base)
2500
interesting_files = [path]
2502
interesting_files = None
2503
pb = ui.ui_factory.nested_progress_bar()
2506
conflict_count = _merge_helper(
2507
other, base, check_clean=(not force),
2508
merge_type=merge_type,
2509
reprocess=reprocess,
2510
show_base=show_base,
2513
pb=pb, file_list=interesting_files,
2514
change_reporter=change_reporter)
2517
if conflict_count != 0:
2890
raise errors.BzrCommandError('Cannot use --uncommitted'
2891
' with bundles or merge directives.')
2893
if revision is not None:
2894
raise errors.BzrCommandError(
2895
'Cannot use -r with merge directives or bundles')
2896
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2899
if merger is None and uncommitted:
2900
if revision is not None and len(revision) > 0:
2901
raise errors.BzrCommandError('Cannot use --uncommitted and'
2902
' --revision at the same time.')
2903
location = self._select_branch_location(tree, location)[0]
2904
other_tree, other_path = WorkingTree.open_containing(location)
2905
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2907
allow_pending = False
2908
if other_path != '':
2909
merger.interesting_files = [other_path]
2912
merger, allow_pending = self._get_merger_from_branch(tree,
2913
location, revision, remember, possible_transports, pb)
2915
merger.merge_type = merge_type
2916
merger.reprocess = reprocess
2917
merger.show_base = show_base
2918
self.sanity_check_merger(merger)
2919
if (merger.base_rev_id == merger.other_rev_id and
2920
merger.other_rev_id != None):
2921
note('Nothing to do.')
2521
except errors.AmbiguousBase, e:
2522
m = ("sorry, bzr can't determine the right merge base yet\n"
2523
"candidates are:\n "
2524
+ "\n ".join(e.bases)
2526
"please specify an explicit base with -r,\n"
2527
"and (if you want) report this to the bzr developers\n")
2530
# TODO: move up to common parent; this isn't merge-specific anymore.
2531
def _get_remembered_parent(self, tree, supplied_location, verb_string):
2924
if merger.interesting_files is not None:
2925
raise errors.BzrCommandError('Cannot pull individual files')
2926
if (merger.base_rev_id == tree.last_revision()):
2927
result = tree.pull(merger.other_branch, False,
2928
merger.other_rev_id)
2929
result.report(self.outf)
2931
merger.check_basis(not force)
2933
return self._do_preview(merger)
2935
return self._do_merge(merger, change_reporter, allow_pending,
2938
for cleanup in reversed(cleanups):
2941
def _do_preview(self, merger):
2942
from bzrlib.diff import show_diff_trees
2943
tree_merger = merger.make_merger()
2944
tt = tree_merger.make_preview_transform()
2946
result_tree = tt.get_preview_tree()
2947
show_diff_trees(merger.this_tree, result_tree, self.outf,
2948
old_label='', new_label='')
2952
def _do_merge(self, merger, change_reporter, allow_pending, verified):
2953
merger.change_reporter = change_reporter
2954
conflict_count = merger.do_merge()
2956
merger.set_pending()
2957
if verified == 'failed':
2958
warning('Preview patch does not match changes')
2959
if conflict_count != 0:
2964
def sanity_check_merger(self, merger):
2965
if (merger.show_base and
2966
not merger.merge_type is _mod_merge.Merge3Merger):
2967
raise errors.BzrCommandError("Show-base is not supported for this"
2968
" merge type. %s" % merger.merge_type)
2969
if merger.reprocess and not merger.merge_type.supports_reprocess:
2970
raise errors.BzrCommandError("Conflict reduction is not supported"
2971
" for merge type %s." %
2973
if merger.reprocess and merger.show_base:
2974
raise errors.BzrCommandError("Cannot do conflict reduction and"
2977
def _get_merger_from_branch(self, tree, location, revision, remember,
2978
possible_transports, pb):
2979
"""Produce a merger from a location, assuming it refers to a branch."""
2980
from bzrlib.tag import _merge_tags_if_possible
2981
assert revision is None or len(revision) < 3
2982
# find the branch locations
2983
other_loc, user_location = self._select_branch_location(tree, location,
2985
if revision is not None and len(revision) == 2:
2986
base_loc, _unused = self._select_branch_location(tree,
2987
location, revision, 0)
2989
base_loc = other_loc
2991
other_branch, other_path = Branch.open_containing(other_loc,
2992
possible_transports)
2993
if base_loc == other_loc:
2994
base_branch = other_branch
2996
base_branch, base_path = Branch.open_containing(base_loc,
2997
possible_transports)
2998
# Find the revision ids
2999
if revision is None or len(revision) < 1 or revision[-1] is None:
3000
other_revision_id = _mod_revision.ensure_null(
3001
other_branch.last_revision())
3003
other_revision_id = revision[-1].as_revision_id(other_branch)
3004
if (revision is not None and len(revision) == 2
3005
and revision[0] is not None):
3006
base_revision_id = revision[0].as_revision_id(base_branch)
3008
base_revision_id = None
3009
# Remember where we merge from
3010
if ((remember or tree.branch.get_submit_branch() is None) and
3011
user_location is not None):
3012
tree.branch.set_submit_branch(other_branch.base)
3013
_merge_tags_if_possible(other_branch, tree.branch)
3014
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
3015
other_revision_id, base_revision_id, other_branch, base_branch)
3016
if other_path != '':
3017
allow_pending = False
3018
merger.interesting_files = [other_path]
3020
allow_pending = True
3021
return merger, allow_pending
3023
def _select_branch_location(self, tree, user_location, revision=None,
3025
"""Select a branch location, according to possible inputs.
3027
If provided, branches from ``revision`` are preferred. (Both
3028
``revision`` and ``index`` must be supplied.)
3030
Otherwise, the ``location`` parameter is used. If it is None, then the
3031
``submit`` or ``parent`` location is used, and a note is printed.
3033
:param tree: The working tree to select a branch for merging into
3034
:param location: The location entered by the user
3035
:param revision: The revision parameter to the command
3036
:param index: The index to use for the revision parameter. Negative
3037
indices are permitted.
3038
:return: (selected_location, user_location). The default location
3039
will be the user-entered location.
3041
if (revision is not None and index is not None
3042
and revision[index] is not None):
3043
branch = revision[index].get_branch()
3044
if branch is not None:
3045
return branch, branch
3046
if user_location is None:
3047
location = self._get_remembered(tree, 'Merging from')
3049
location = user_location
3050
return location, user_location
3052
def _get_remembered(self, tree, verb_string):
2532
3053
"""Use tree.branch's parent if none was supplied.
2534
3055
Report if the remembered location was used.
2536
if supplied_location is not None:
2537
return supplied_location
2538
stored_location = tree.branch.get_parent()
3057
stored_location = tree.branch.get_submit_branch()
3058
if stored_location is None:
3059
stored_location = tree.branch.get_parent()
2539
3060
mutter("%s", stored_location)
2540
3061
if stored_location is None:
2541
3062
raise errors.BzrCommandError("No location specified or remembered")
2542
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2543
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
3063
display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
3064
note(u"%s remembered location %s", verb_string, display_url)
2544
3065
return stored_location
3133
3808
takes_options = [
3135
help='serve on stdin/out for use from inetd or sshd'),
3810
help='Serve on stdin/out for use from inetd or sshd.'),
3137
help='listen for connections on nominated port of the form '
3138
'[hostname:]portnumber. Passing 0 as the port number will '
3139
'result in a dynamically allocated port.',
3812
help='Listen for connections on nominated port of the form '
3813
'[hostname:]portnumber. Passing 0 as the port number will '
3814
'result in a dynamically allocated port. The default port is '
3141
3817
Option('directory',
3142
help='serve contents of directory',
3818
help='Serve contents of this directory.',
3144
3820
Option('allow-writes',
3145
help='By default the server is a readonly server. Supplying '
3821
help='By default the server is a readonly server. Supplying '
3146
3822
'--allow-writes enables write access to the contents of '
3147
'the served directory and below. '
3823
'the served directory and below.'
3151
3827
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3152
from bzrlib.transport import smart
3828
from bzrlib import lockdir
3829
from bzrlib.smart import medium, server
3153
3830
from bzrlib.transport import get_transport
3831
from bzrlib.transport.chroot import ChrootServer
3154
3832
if directory is None:
3155
3833
directory = os.getcwd()
3156
3834
url = urlutils.local_path_to_url(directory)
3157
3835
if not allow_writes:
3158
3836
url = 'readonly+' + url
3159
t = get_transport(url)
3837
chroot_server = ChrootServer(get_transport(url))
3838
chroot_server.setUp()
3839
t = get_transport(chroot_server.get_url())
3161
server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
3162
elif port is not None:
3164
host, port = port.split(':')
3841
smart_server = medium.SmartServerPipeStreamMedium(
3842
sys.stdin, sys.stdout, t)
3844
host = medium.BZR_DEFAULT_INTERFACE
3846
port = medium.BZR_DEFAULT_PORT
3167
server = smart.SmartTCPServer(t, host=host, port=int(port))
3168
print 'listening on port: ', server.port
3849
host, port = port.split(':')
3851
smart_server = server.SmartTCPServer(t, host=host, port=port)
3852
print 'listening on port: ', smart_server.port
3169
3853
sys.stdout.flush()
3171
raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
3175
# command-line interpretation helper for merge-related commands
3176
def _merge_helper(other_revision, base_revision,
3177
check_clean=True, ignore_zero=False,
3178
this_dir=None, backup_files=False,
3180
file_list=None, show_base=False, reprocess=False,
3183
change_reporter=None):
3184
"""Merge changes into a tree.
3187
list(path, revno) Base for three-way merge.
3188
If [None, None] then a base will be automatically determined.
3190
list(path, revno) Other revision for three-way merge.
3192
Directory to merge changes into; '.' by default.
3194
If true, this_dir must have no uncommitted changes before the
3196
ignore_zero - If true, suppress the "zero conflicts" message when
3197
there are no conflicts; should be set when doing something we expect
3198
to complete perfectly.
3199
file_list - If supplied, merge only changes to selected files.
3201
All available ancestors of other_revision and base_revision are
3202
automatically pulled into the branch.
3204
The revno may be -1 to indicate the last revision on the branch, which is
3207
This function is intended for use from the command line; programmatic
3208
clients might prefer to call merge.merge_inner(), which has less magic
3211
# Loading it late, so that we don't always have to import bzrlib.merge
3212
if merge_type is None:
3213
merge_type = _mod_merge.Merge3Merger
3214
if this_dir is None:
3216
this_tree = WorkingTree.open_containing(this_dir)[0]
3217
if show_base and not merge_type is _mod_merge.Merge3Merger:
3218
raise errors.BzrCommandError("Show-base is not supported for this merge"
3219
" type. %s" % merge_type)
3220
if reprocess and not merge_type.supports_reprocess:
3221
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3222
" type %s." % merge_type)
3223
if reprocess and show_base:
3224
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3226
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3227
pb=pb, change_reporter=change_reporter)
3228
merger.pp = ProgressPhase("Merge phase", 5, pb)
3229
merger.pp.next_phase()
3230
merger.check_basis(check_clean)
3231
merger.set_other(other_revision)
3232
merger.pp.next_phase()
3233
merger.set_base(base_revision)
3234
if merger.base_rev_id == merger.other_rev_id:
3235
note('Nothing to do.')
3237
if file_list is None:
3238
if pull and merger.base_rev_id == merger.this_rev_id:
3239
count = merger.this_tree.pull(merger.this_branch,
3240
False, merger.other_rev_id)
3241
note('%d revision(s) pulled.' % (count,))
3243
merger.backup_files = backup_files
3244
merger.merge_type = merge_type
3245
merger.set_interesting_files(file_list)
3246
merger.show_base = show_base
3247
merger.reprocess = reprocess
3248
conflicts = merger.do_merge()
3249
if file_list is None:
3250
merger.set_pending()
3257
merge = _merge_helper
3854
# for the duration of this server, no UI output is permitted.
3855
# note that this may cause problems with blackbox tests. This should
3856
# be changed with care though, as we dont want to use bandwidth sending
3857
# progress over stderr to smart server clients!
3858
old_factory = ui.ui_factory
3859
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
3861
ui.ui_factory = ui.SilentUIFactory()
3862
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
3863
smart_server.serve()
3865
ui.ui_factory = old_factory
3866
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
3869
class cmd_join(Command):
3870
"""Combine a subtree into its containing tree.
3872
This command is for experimental use only. It requires the target tree
3873
to be in dirstate-with-subtree format, which cannot be converted into
3876
The TREE argument should be an independent tree, inside another tree, but
3877
not part of it. (Such trees can be produced by "bzr split", but also by
3878
running "bzr branch" with the target inside a tree.)
3880
The result is a combined tree, with the subtree no longer an independant
3881
part. This is marked as a merge of the subtree into the containing tree,
3882
and all history is preserved.
3884
If --reference is specified, the subtree retains its independence. It can
3885
be branched by itself, and can be part of multiple projects at the same
3886
time. But operations performed in the containing tree, such as commit
3887
and merge, will recurse into the subtree.
3890
_see_also = ['split']
3891
takes_args = ['tree']
3893
Option('reference', help='Join by reference.'),
3897
def run(self, tree, reference=False):
3898
sub_tree = WorkingTree.open(tree)
3899
parent_dir = osutils.dirname(sub_tree.basedir)
3900
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3901
repo = containing_tree.branch.repository
3902
if not repo.supports_rich_root():
3903
raise errors.BzrCommandError(
3904
"Can't join trees because %s doesn't support rich root data.\n"
3905
"You can use bzr upgrade on the repository."
3909
containing_tree.add_reference(sub_tree)
3910
except errors.BadReferenceTarget, e:
3911
# XXX: Would be better to just raise a nicely printable
3912
# exception from the real origin. Also below. mbp 20070306
3913
raise errors.BzrCommandError("Cannot join %s. %s" %
3917
containing_tree.subsume(sub_tree)
3918
except errors.BadSubsumeSource, e:
3919
raise errors.BzrCommandError("Cannot join %s. %s" %
3923
class cmd_split(Command):
3924
"""Split a subdirectory of a tree into a separate tree.
3926
This command will produce a target tree in a format that supports
3927
rich roots, like 'rich-root' or 'rich-root-pack'. These formats cannot be
3928
converted into earlier formats like 'dirstate-tags'.
3930
The TREE argument should be a subdirectory of a working tree. That
3931
subdirectory will be converted into an independent tree, with its own
3932
branch. Commits in the top-level tree will not apply to the new subtree.
3935
# join is not un-hidden yet
3936
#_see_also = ['join']
3937
takes_args = ['tree']
3939
def run(self, tree):
3940
containing_tree, subdir = WorkingTree.open_containing(tree)
3941
sub_id = containing_tree.path2id(subdir)
3943
raise errors.NotVersionedError(subdir)
3945
containing_tree.extract(sub_id)
3946
except errors.RootNotRich:
3947
raise errors.UpgradeRequired(containing_tree.branch.base)
3950
class cmd_merge_directive(Command):
3951
"""Generate a merge directive for auto-merge tools.
3953
A directive requests a merge to be performed, and also provides all the
3954
information necessary to do so. This means it must either include a
3955
revision bundle, or the location of a branch containing the desired
3958
A submit branch (the location to merge into) must be supplied the first
3959
time the command is issued. After it has been supplied once, it will
3960
be remembered as the default.
3962
A public branch is optional if a revision bundle is supplied, but required
3963
if --diff or --plain is specified. It will be remembered as the default
3964
after the first use.
3967
takes_args = ['submit_branch?', 'public_branch?']
3971
_see_also = ['send']
3974
RegistryOption.from_kwargs('patch-type',
3975
'The type of patch to include in the directive.',
3977
value_switches=True,
3979
bundle='Bazaar revision bundle (default).',
3980
diff='Normal unified diff.',
3981
plain='No patch, just directive.'),
3982
Option('sign', help='GPG-sign the directive.'), 'revision',
3983
Option('mail-to', type=str,
3984
help='Instead of printing the directive, email to this address.'),
3985
Option('message', type=str, short_name='m',
3986
help='Message to use when committing this merge.')
3989
encoding_type = 'exact'
3991
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3992
sign=False, revision=None, mail_to=None, message=None):
3993
from bzrlib.revision import ensure_null, NULL_REVISION
3994
include_patch, include_bundle = {
3995
'plain': (False, False),
3996
'diff': (True, False),
3997
'bundle': (True, True),
3999
branch = Branch.open('.')
4000
stored_submit_branch = branch.get_submit_branch()
4001
if submit_branch is None:
4002
submit_branch = stored_submit_branch
4004
if stored_submit_branch is None:
4005
branch.set_submit_branch(submit_branch)
4006
if submit_branch is None:
4007
submit_branch = branch.get_parent()
4008
if submit_branch is None:
4009
raise errors.BzrCommandError('No submit branch specified or known')
4011
stored_public_branch = branch.get_public_branch()
4012
if public_branch is None:
4013
public_branch = stored_public_branch
4014
elif stored_public_branch is None:
4015
branch.set_public_branch(public_branch)
4016
if not include_bundle and public_branch is None:
4017
raise errors.BzrCommandError('No public branch specified or'
4019
base_revision_id = None
4020
if revision is not None:
4021
if len(revision) > 2:
4022
raise errors.BzrCommandError('bzr merge-directive takes '
4023
'at most two one revision identifiers')
4024
revision_id = revision[-1].as_revision_id(branch)
4025
if len(revision) == 2:
4026
base_revision_id = revision[0].as_revision_id(branch)
4028
revision_id = branch.last_revision()
4029
revision_id = ensure_null(revision_id)
4030
if revision_id == NULL_REVISION:
4031
raise errors.BzrCommandError('No revisions to bundle.')
4032
directive = merge_directive.MergeDirective2.from_objects(
4033
branch.repository, revision_id, time.time(),
4034
osutils.local_time_offset(), submit_branch,
4035
public_branch=public_branch, include_patch=include_patch,
4036
include_bundle=include_bundle, message=message,
4037
base_revision_id=base_revision_id)
4040
self.outf.write(directive.to_signed(branch))
4042
self.outf.writelines(directive.to_lines())
4044
message = directive.to_email(mail_to, branch, sign)
4045
s = SMTPConnection(branch.get_config())
4046
s.send_email(message)
4049
class cmd_send(Command):
4050
"""Mail or create a merge-directive for submiting changes.
4052
A merge directive provides many things needed for requesting merges:
4054
* A machine-readable description of the merge to perform
4056
* An optional patch that is a preview of the changes requested
4058
* An optional bundle of revision data, so that the changes can be applied
4059
directly from the merge directive, without retrieving data from a
4062
If --no-bundle is specified, then public_branch is needed (and must be
4063
up-to-date), so that the receiver can perform the merge using the
4064
public_branch. The public_branch is always included if known, so that
4065
people can check it later.
4067
The submit branch defaults to the parent, but can be overridden. Both
4068
submit branch and public branch will be remembered if supplied.
4070
If a public_branch is known for the submit_branch, that public submit
4071
branch is used in the merge instructions. This means that a local mirror
4072
can be used as your actual submit branch, once you have set public_branch
4075
Mail is sent using your preferred mail program. This should be transparent
4076
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
4077
If the preferred client can't be found (or used), your editor will be used.
4079
To use a specific mail program, set the mail_client configuration option.
4080
(For Thunderbird 1.5, this works around some bugs.) Supported values for
4081
specific clients are "evolution", "kmail", "mutt", and "thunderbird";
4082
generic options are "default", "editor", "mapi", and "xdg-email".
4084
If mail is being sent, a to address is required. This can be supplied
4085
either on the commandline, by setting the submit_to configuration
4086
option in the branch itself or the child_submit_to configuration option
4087
in the submit branch.
4089
Two formats are currently supported: "4" uses revision bundle format 4 and
4090
merge directive format 2. It is significantly faster and smaller than
4091
older formats. It is compatible with Bazaar 0.19 and later. It is the
4092
default. "0.9" uses revision bundle format 0.9 and merge directive
4093
format 1. It is compatible with Bazaar 0.12 - 0.18.
4095
Merge directives are applied using the merge command or the pull command.
4098
encoding_type = 'exact'
4100
_see_also = ['merge', 'pull']
4102
takes_args = ['submit_branch?', 'public_branch?']
4106
help='Do not include a bundle in the merge directive.'),
4107
Option('no-patch', help='Do not include a preview patch in the merge'
4110
help='Remember submit and public branch.'),
4112
help='Branch to generate the submission from, '
4113
'rather than the one containing the working directory.',
4116
Option('output', short_name='o',
4117
help='Write merge directive to this file; '
4118
'use - for stdout.',
4120
Option('mail-to', help='Mail the request to this address.',
4124
RegistryOption.from_kwargs('format',
4125
'Use the specified output format.',
4126
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4127
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4130
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4131
no_patch=False, revision=None, remember=False, output=None,
4132
format='4', mail_to=None, message=None, **kwargs):
4133
return self._run(submit_branch, revision, public_branch, remember,
4134
format, no_bundle, no_patch, output,
4135
kwargs.get('from', '.'), mail_to, message)
4137
def _run(self, submit_branch, revision, public_branch, remember, format,
4138
no_bundle, no_patch, output, from_, mail_to, message):
4139
from bzrlib.revision import NULL_REVISION
4140
branch = Branch.open_containing(from_)[0]
4142
outfile = StringIO()
4146
outfile = open(output, 'wb')
4147
# we may need to write data into branch's repository to calculate
4152
config = branch.get_config()
4154
mail_to = config.get_user_option('submit_to')
4155
mail_client = config.get_mail_client()
4156
if remember and submit_branch is None:
4157
raise errors.BzrCommandError(
4158
'--remember requires a branch to be specified.')
4159
stored_submit_branch = branch.get_submit_branch()
4160
remembered_submit_branch = False
4161
if submit_branch is None:
4162
submit_branch = stored_submit_branch
4163
remembered_submit_branch = True
4165
if stored_submit_branch is None or remember:
4166
branch.set_submit_branch(submit_branch)
4167
if submit_branch is None:
4168
submit_branch = branch.get_parent()
4169
remembered_submit_branch = True
4170
if submit_branch is None:
4171
raise errors.BzrCommandError('No submit branch known or'
4173
if remembered_submit_branch:
4174
note('Using saved location: %s', submit_branch)
4177
submit_config = Branch.open(submit_branch).get_config()
4178
mail_to = submit_config.get_user_option("child_submit_to")
4180
stored_public_branch = branch.get_public_branch()
4181
if public_branch is None:
4182
public_branch = stored_public_branch
4183
elif stored_public_branch is None or remember:
4184
branch.set_public_branch(public_branch)
4185
if no_bundle and public_branch is None:
4186
raise errors.BzrCommandError('No public branch specified or'
4188
base_revision_id = None
4190
if revision is not None:
4191
if len(revision) > 2:
4192
raise errors.BzrCommandError('bzr send takes '
4193
'at most two one revision identifiers')
4194
revision_id = revision[-1].as_revision_id(branch)
4195
if len(revision) == 2:
4196
base_revision_id = revision[0].as_revision_id(branch)
4197
if revision_id is None:
4198
revision_id = branch.last_revision()
4199
if revision_id == NULL_REVISION:
4200
raise errors.BzrCommandError('No revisions to submit.')
4202
directive = merge_directive.MergeDirective2.from_objects(
4203
branch.repository, revision_id, time.time(),
4204
osutils.local_time_offset(), submit_branch,
4205
public_branch=public_branch, include_patch=not no_patch,
4206
include_bundle=not no_bundle, message=message,
4207
base_revision_id=base_revision_id)
4208
elif format == '0.9':
4211
patch_type = 'bundle'
4213
raise errors.BzrCommandError('Format 0.9 does not'
4214
' permit bundle with no patch')
4220
directive = merge_directive.MergeDirective.from_objects(
4221
branch.repository, revision_id, time.time(),
4222
osutils.local_time_offset(), submit_branch,
4223
public_branch=public_branch, patch_type=patch_type,
4226
outfile.writelines(directive.to_lines())
4228
subject = '[MERGE] '
4229
if message is not None:
4232
revision = branch.repository.get_revision(revision_id)
4233
subject += revision.get_summary()
4234
basename = directive.get_disk_name(branch)
4235
mail_client.compose_merge_request(mail_to, subject,
4236
outfile.getvalue(), basename)
4243
class cmd_bundle_revisions(cmd_send):
4245
"""Create a merge-directive for submiting changes.
4247
A merge directive provides many things needed for requesting merges:
4249
* A machine-readable description of the merge to perform
4251
* An optional patch that is a preview of the changes requested
4253
* An optional bundle of revision data, so that the changes can be applied
4254
directly from the merge directive, without retrieving data from a
4257
If --no-bundle is specified, then public_branch is needed (and must be
4258
up-to-date), so that the receiver can perform the merge using the
4259
public_branch. The public_branch is always included if known, so that
4260
people can check it later.
4262
The submit branch defaults to the parent, but can be overridden. Both
4263
submit branch and public branch will be remembered if supplied.
4265
If a public_branch is known for the submit_branch, that public submit
4266
branch is used in the merge instructions. This means that a local mirror
4267
can be used as your actual submit branch, once you have set public_branch
4270
Two formats are currently supported: "4" uses revision bundle format 4 and
4271
merge directive format 2. It is significantly faster and smaller than
4272
older formats. It is compatible with Bazaar 0.19 and later. It is the
4273
default. "0.9" uses revision bundle format 0.9 and merge directive
4274
format 1. It is compatible with Bazaar 0.12 - 0.18.
4279
help='Do not include a bundle in the merge directive.'),
4280
Option('no-patch', help='Do not include a preview patch in the merge'
4283
help='Remember submit and public branch.'),
4285
help='Branch to generate the submission from, '
4286
'rather than the one containing the working directory.',
4289
Option('output', short_name='o', help='Write directive to this file.',
4292
RegistryOption.from_kwargs('format',
4293
'Use the specified output format.',
4294
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4295
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4297
aliases = ['bundle']
4299
_see_also = ['send', 'merge']
4303
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4304
no_patch=False, revision=None, remember=False, output=None,
4305
format='4', **kwargs):
4308
return self._run(submit_branch, revision, public_branch, remember,
4309
format, no_bundle, no_patch, output,
4310
kwargs.get('from', '.'), None, None)
4313
class cmd_tag(Command):
4314
"""Create, remove or modify a tag naming a revision.
4316
Tags give human-meaningful names to revisions. Commands that take a -r
4317
(--revision) option can be given -rtag:X, where X is any previously
4320
Tags are stored in the branch. Tags are copied from one branch to another
4321
along when you branch, push, pull or merge.
4323
It is an error to give a tag name that already exists unless you pass
4324
--force, in which case the tag is moved to point to the new revision.
4327
_see_also = ['commit', 'tags']
4328
takes_args = ['tag_name']
4331
help='Delete this tag rather than placing it.',
4334
help='Branch in which to place the tag.',
4339
help='Replace existing tags.',
4344
def run(self, tag_name,
4350
branch, relpath = Branch.open_containing(directory)
4354
branch.tags.delete_tag(tag_name)
4355
self.outf.write('Deleted tag %s.\n' % tag_name)
4358
if len(revision) != 1:
4359
raise errors.BzrCommandError(
4360
"Tags can only be placed on a single revision, "
4362
revision_id = revision[0].as_revision_id(branch)
4364
revision_id = branch.last_revision()
4365
if (not force) and branch.tags.has_tag(tag_name):
4366
raise errors.TagAlreadyExists(tag_name)
4367
branch.tags.set_tag(tag_name, revision_id)
4368
self.outf.write('Created tag %s.\n' % tag_name)
4373
class cmd_tags(Command):
4376
This command shows a table of tag names and the revisions they reference.
4382
help='Branch whose tags should be displayed.',
4386
RegistryOption.from_kwargs('sort',
4387
'Sort tags by different criteria.', title='Sorting',
4388
alpha='Sort tags lexicographically (default).',
4389
time='Sort tags chronologically.',
4400
branch, relpath = Branch.open_containing(directory)
4401
tags = branch.tags.get_tag_dict().items()
4404
elif sort == 'time':
4406
for tag, revid in tags:
4408
revobj = branch.repository.get_revision(revid)
4409
except errors.NoSuchRevision:
4410
timestamp = sys.maxint # place them at the end
4412
timestamp = revobj.timestamp
4413
timestamps[revid] = timestamp
4414
tags.sort(key=lambda x: timestamps[x[1]])
4416
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
4417
revno_map = branch.get_revision_id_to_revno_map()
4418
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
4419
for tag, revid in tags ]
4420
for tag, revspec in tags:
4421
self.outf.write('%-20s %s\n' % (tag, revspec))
4424
class cmd_reconfigure(Command):
4425
"""Reconfigure the type of a bzr directory.
4427
A target configuration must be specified.
4429
For checkouts, the bind-to location will be auto-detected if not specified.
4430
The order of preference is
4431
1. For a lightweight checkout, the current bound location.
4432
2. For branches that used to be checkouts, the previously-bound location.
4433
3. The push location.
4434
4. The parent location.
4435
If none of these is available, --bind-to must be specified.
4438
takes_args = ['location?']
4439
takes_options = [RegistryOption.from_kwargs('target_type',
4440
title='Target type',
4441
help='The type to reconfigure the directory to.',
4442
value_switches=True, enum_switch=False,
4443
branch='Reconfigure to a branch.',
4444
tree='Reconfigure to a tree.',
4445
checkout='Reconfigure to a checkout.',
4446
lightweight_checkout='Reconfigure to a lightweight'
4448
standalone='Reconfigure to be standalone.',
4449
use_shared='Reconfigure to use a shared repository.'),
4450
Option('bind-to', help='Branch to bind checkout to.',
4453
help='Perform reconfiguration even if local changes'
4457
def run(self, location=None, target_type=None, bind_to=None, force=False):
4458
directory = bzrdir.BzrDir.open(location)
4459
if target_type is None:
4460
raise errors.BzrCommandError('No target configuration specified')
4461
elif target_type == 'branch':
4462
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4463
elif target_type == 'tree':
4464
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4465
elif target_type == 'checkout':
4466
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4468
elif target_type == 'lightweight-checkout':
4469
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4471
elif target_type == 'use-shared':
4472
reconfiguration = reconfigure.Reconfigure.to_use_shared(directory)
4473
elif target_type == 'standalone':
4474
reconfiguration = reconfigure.Reconfigure.to_standalone(directory)
4475
reconfiguration.apply(force)
4478
class cmd_switch(Command):
4479
"""Set the branch of a checkout and update.
4481
For lightweight checkouts, this changes the branch being referenced.
4482
For heavyweight checkouts, this checks that there are no local commits
4483
versus the current bound branch, then it makes the local branch a mirror
4484
of the new location and binds to it.
4486
In both cases, the working tree is updated and uncommitted changes
4487
are merged. The user can commit or revert these as they desire.
4489
Pending merges need to be committed or reverted before using switch.
4491
The path to the branch to switch to can be specified relative to the parent
4492
directory of the current branch. For example, if you are currently in a
4493
checkout of /path/to/branch, specifying 'newbranch' will find a branch at
4497
takes_args = ['to_location']
4498
takes_options = [Option('force',
4499
help='Switch even if local commits will be lost.')
4502
def run(self, to_location, force=False):
4503
from bzrlib import switch
4505
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4507
to_branch = Branch.open(to_location)
4508
except errors.NotBranchError:
4509
to_branch = Branch.open(
4510
control_dir.open_branch().base + '../' + to_location)
4511
switch.switch(control_dir, to_branch, force)
4512
note('Switched to branch: %s',
4513
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4516
class cmd_hooks(Command):
4517
"""Show a branch's currently registered hooks.
4521
takes_args = ['path?']
4523
def run(self, path=None):
4526
branch_hooks = Branch.open(path).hooks
4527
for hook_type in branch_hooks:
4528
hooks = branch_hooks[hook_type]
4529
self.outf.write("%s:\n" % (hook_type,))
4532
self.outf.write(" %s\n" %
4533
(branch_hooks.get_hook_name(hook),))
4535
self.outf.write(" <no hooks installed>\n")
4538
def _create_prefix(cur_transport):
4539
needed = [cur_transport]
4540
# Recurse upwards until we can create a directory successfully
4542
new_transport = cur_transport.clone('..')
4543
if new_transport.base == cur_transport.base:
4544
raise errors.BzrCommandError(
4545
"Failed to create path prefix for %s."
4546
% cur_transport.base)
4548
new_transport.mkdir('.')
4549
except errors.NoSuchFile:
4550
needed.append(new_transport)
4551
cur_transport = new_transport
4554
# Now we only need to create child directories
4556
cur_transport = needed.pop()
4557
cur_transport.ensure_base()
3260
4560
# these get imported and then picked up by the scan for cmd_*