1365
1400
class cmd_diff(Command):
1366
"""Show differences in the working tree or between revisions.
1401
"""Show differences in the working tree, between revisions or branches.
1368
If files are listed, only the changes in those files are listed.
1369
Otherwise, all changes for the tree are listed.
1403
If no arguments are given, all changes for the current tree are listed.
1404
If files are given, only the changes in those files are listed.
1405
Remote and multiple branches can be compared by using the --old and
1406
--new options. If not provided, the default for both is derived from
1407
the first argument, if any, or the current tree if no arguments are
1371
1410
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1372
1411
produces patches suitable for "patch -p1".
1376
Shows the difference in the working tree versus the last commit
1378
Difference between the working tree and revision 1
1380
Difference between revision 2 and revision 1
1381
bzr diff --prefix old/:new/
1382
Same as 'bzr diff' but prefix paths with old/ and new/
1383
bzr diff bzr.mine bzr.dev
1384
Show the differences between the two working trees
1386
Show just the differences for 'foo.c'
1415
2 - unrepresentable changes
1420
Shows the difference in the working tree versus the last commit::
1424
Difference between the working tree and revision 1::
1428
Difference between revision 2 and revision 1::
1432
Difference between revision 2 and revision 1 for branch xxx::
1436
Show just the differences for file NEWS::
1440
Show the differences in working tree xxx for file NEWS::
1444
Show the differences from branch xxx to this working tree:
1448
Show the differences between two branches for file NEWS::
1450
bzr diff --old xxx --new yyy NEWS
1452
Same as 'bzr diff' but prefix paths with old/ and new/::
1454
bzr diff --prefix old/:new/
1388
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1389
# or a graphical diff.
1391
# TODO: Python difflib is not exactly the same as unidiff; should
1392
# either fix it up or prefer to use an external diff.
1394
# TODO: Selected-file diff is inefficient and doesn't show you
1397
# TODO: This probably handles non-Unix newlines poorly.
1399
1456
_see_also = ['status']
1400
1457
takes_args = ['file*']
1401
takes_options = ['revision', 'diff-options',
1459
Option('diff-options', type=str,
1460
help='Pass these options to the external diff program.'),
1402
1461
Option('prefix', type=str,
1403
1462
short_name='p',
1404
help='Set prefixes to added to old and new filenames, as '
1405
'two values separated by a colon. (eg "old/:new/")'),
1463
help='Set prefixes added to old and new filenames, as '
1464
'two values separated by a colon. (eg "old/:new/").'),
1466
help='Branch/tree to compare from.',
1470
help='Branch/tree to compare to.',
1476
help='Use this command to compare files.',
1407
1480
aliases = ['di', 'dif']
1408
1481
encoding_type = 'exact'
1410
1483
@display_command
1411
1484
def run(self, revision=None, file_list=None, diff_options=None,
1413
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1485
prefix=None, old=None, new=None, using=None):
1486
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1415
1488
if (prefix is None) or (prefix == '0'):
1416
1489
# diff -p0 format
1430
1503
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1431
1504
' one or two revision specifiers')
1434
tree1, file_list = internal_tree_files(file_list)
1438
except errors.FileInWrongBranch:
1439
if len(file_list) != 2:
1440
raise errors.BzrCommandError("Files are in different branches")
1442
tree1, file1 = WorkingTree.open_containing(file_list[0])
1443
tree2, file2 = WorkingTree.open_containing(file_list[1])
1444
if file1 != "" or file2 != "":
1445
# FIXME diff those two files. rbc 20051123
1446
raise errors.BzrCommandError("Files are in different branches")
1448
except errors.NotBranchError:
1449
if (revision is not None and len(revision) == 2
1450
and not revision[0].needs_branch()
1451
and not revision[1].needs_branch()):
1452
# If both revision specs include a branch, we can
1453
# diff them without needing a local working tree
1454
tree1, tree2 = None, None
1458
if tree2 is not None:
1459
if revision is not None:
1460
# FIXME: but there should be a clean way to diff between
1461
# non-default versions of two trees, it's not hard to do
1463
raise errors.BzrCommandError(
1464
"Sorry, diffing arbitrary revisions across branches "
1465
"is not implemented yet")
1466
return show_diff_trees(tree1, tree2, sys.stdout,
1467
specific_files=file_list,
1468
external_diff_options=diff_options,
1469
old_label=old_label, new_label=new_label)
1471
return diff_cmd_helper(tree1, file_list, diff_options,
1472
revision_specs=revision,
1473
old_label=old_label, new_label=new_label)
1506
old_tree, new_tree, specific_files, extra_trees = \
1507
_get_trees_to_diff(file_list, revision, old, new)
1508
return show_diff_trees(old_tree, new_tree, sys.stdout,
1509
specific_files=specific_files,
1510
external_diff_options=diff_options,
1511
old_label=old_label, new_label=new_label,
1512
extra_trees=extra_trees, using=using)
1476
1515
class cmd_deleted(Command):
2421
2568
takes_args = ['testspecs*']
2422
2569
takes_options = ['verbose',
2424
help='stop when one test fails',
2571
help='Stop when one test fails.',
2425
2572
short_name='1',
2427
Option('keep-output',
2428
help='keep output directories when tests fail'),
2429
2574
Option('transport',
2430
2575
help='Use a different transport by default '
2431
2576
'throughout the test suite.',
2432
2577
type=get_transport_type),
2433
Option('benchmark', help='run the bzr benchmarks.'),
2579
help='Run the benchmarks rather than selftests.'),
2434
2580
Option('lsprof-timed',
2435
help='generate lsprof output for benchmarked'
2581
help='Generate lsprof output for benchmarked'
2436
2582
' sections of code.'),
2437
2583
Option('cache-dir', type=str,
2438
help='a directory to cache intermediate'
2439
' benchmark steps'),
2440
Option('clean-output',
2441
help='clean temporary tests directories'
2442
' without running tests'),
2584
help='Cache intermediate benchmark output in this '
2443
2586
Option('first',
2444
help='run all tests, but run specified tests first',
2587
help='Run all tests, but run specified tests first.',
2445
2588
short_name='f',
2447
Option('numbered-dirs',
2448
help='use numbered dirs for TestCaseInTempDir'),
2449
2590
Option('list-only',
2450
help='list the tests instead of running them'),
2591
help='List the tests instead of running them.'),
2451
2592
Option('randomize', type=str, argname="SEED",
2452
help='randomize the order of tests using the given'
2453
' seed or "now" for the current time'),
2593
help='Randomize the order of tests using the given'
2594
' seed or "now" for the current time.'),
2454
2595
Option('exclude', type=str, argname="PATTERN",
2455
2596
short_name='x',
2456
help='exclude tests that match this regular'
2597
help='Exclude tests that match this regular'
2599
Option('strict', help='Fail on missing dependencies or '
2601
Option('coverage', type=str, argname="DIRECTORY",
2602
help='Generate line coverage report in this '
2459
2605
encoding_type = 'replace'
2461
def run(self, testspecs_list=None, verbose=None, one=False,
2462
keep_output=False, transport=None, benchmark=None,
2463
lsprof_timed=None, cache_dir=None, clean_output=False,
2464
first=False, numbered_dirs=None, list_only=False,
2465
randomize=None, exclude=None):
2607
def run(self, testspecs_list=None, verbose=False, one=False,
2608
transport=None, benchmark=None,
2609
lsprof_timed=None, cache_dir=None,
2610
first=False, list_only=False,
2611
randomize=None, exclude=None, strict=False, coverage=None):
2466
2612
import bzrlib.ui
2467
2613
from bzrlib.tests import selftest
2468
2614
import bzrlib.benchmarks as benchmarks
2469
2615
from bzrlib.benchmarks import tree_creator
2472
from bzrlib.tests import clean_selftest_output
2473
clean_selftest_output()
2476
trace.warning("notice: selftest --keep-output "
2477
"is no longer supported; "
2478
"test output is always removed")
2480
if numbered_dirs is None and sys.platform == 'win32':
2481
numbered_dirs = True
2483
2617
if cache_dir is not None:
2484
2618
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2485
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2486
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2620
print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
2621
print ' %s (%s python%s)' % (
2623
bzrlib.version_string,
2624
'.'.join(map(str, sys.version_info)),
2488
2627
if testspecs_list is not None:
2489
2628
pattern = '|'.join(testspecs_list)
2596
2741
The results of the merge are placed into the destination working
2597
2742
directory, where they can be reviewed (with bzr diff), tested, and then
2598
2743
committed to record the result of the merge.
2602
To merge the latest revision from bzr.dev:
2603
bzr merge ../bzr.dev
2605
To merge changes up to and including revision 82 from bzr.dev:
2606
bzr merge -r 82 ../bzr.dev
2608
To merge the changes introduced by 82, without previous changes:
2609
bzr merge -r 81..82 ../bzr.dev
2611
2745
merge refuses to run if there are any uncommitted changes, unless
2612
2746
--force is given.
2749
To merge the latest revision from bzr.dev::
2751
bzr merge ../bzr.dev
2753
To merge changes up to and including revision 82 from bzr.dev::
2755
bzr merge -r 82 ../bzr.dev
2757
To merge the changes introduced by 82, without previous changes::
2759
bzr merge -r 81..82 ../bzr.dev
2615
_see_also = ['update', 'remerge']
2762
_see_also = ['update', 'remerge', 'status-flags']
2616
2763
takes_args = ['branch?']
2617
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2768
help='Merge even if the destination tree has uncommitted changes.'),
2618
2772
Option('show-base', help="Show base revision text in "
2620
2774
Option('uncommitted', help='Apply uncommitted changes'
2621
' from a working copy, instead of branch changes'),
2775
' from a working copy, instead of branch changes.'),
2622
2776
Option('pull', help='If the destination is already'
2623
2777
' completely merged into the source, pull from the'
2624
' source rather than merging. When this happens,'
2778
' source rather than merging. When this happens,'
2625
2779
' you do not need to commit the result.'),
2626
2780
Option('directory',
2627
help='Branch to merge into, '
2628
'rather than the one containing the working directory',
2781
help='Branch to merge into, '
2782
'rather than the one containing the working directory.',
2634
2788
def run(self, branch=None, revision=None, force=False, merge_type=None,
2636
2790
uncommitted=False, pull=False,
2637
2791
directory=None,
2639
from bzrlib.tag import _merge_tags_if_possible
2640
other_revision_id = None
2793
# This is actually a branch (or merge-directive) *location*.
2641
2797
if merge_type is None:
2642
2798
merge_type = _mod_merge.Merge3Merger
2644
2800
if directory is None: directory = u'.'
2645
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2646
# inventory. Because merge is a mutating operation, it really
2647
# should be a lock_write() for the whole cmd_merge operation.
2648
# However, cmd_merge open's its own tree in _merge_helper, which
2649
# means if we lock here, the later lock_write() will always block.
2650
# Either the merge helper code should be updated to take a tree,
2651
# (What about tree.merge_from_branch?)
2801
possible_transports = []
2803
allow_pending = True
2804
verified = 'inapplicable'
2652
2805
tree = WorkingTree.open_containing(directory)[0]
2653
2806
change_reporter = delta._ChangeReporter(
2654
2807
unversioned_filter=tree.is_ignored)
2656
if branch is not None:
2658
mergeable = bundle.read_mergeable_from_url(
2660
except errors.NotABundle:
2661
pass # Continue on considering this url a Branch
2663
if revision is not None:
2664
raise errors.BzrCommandError(
2665
'Cannot use -r with merge directives or bundles')
2666
other_revision_id = mergeable.install_revisions(
2667
tree.branch.repository)
2668
revision = [RevisionSpec.from_string(
2669
'revid:' + other_revision_id)]
2671
if revision is None \
2672
or len(revision) < 1 or revision[0].needs_branch():
2673
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2675
if revision is None or len(revision) < 1:
2678
other = [branch, None]
2681
other = [branch, -1]
2682
other_branch, path = Branch.open_containing(branch)
2685
raise errors.BzrCommandError('Cannot use --uncommitted and'
2686
' --revision at the same time.')
2687
branch = revision[0].get_branch() or branch
2688
if len(revision) == 1:
2690
if other_revision_id is not None:
2695
other_branch, path = Branch.open_containing(branch)
2696
revno = revision[0].in_history(other_branch).revno
2697
other = [branch, revno]
2699
assert len(revision) == 2
2700
if None in revision:
2701
raise errors.BzrCommandError(
2702
"Merge doesn't permit empty revision specifier.")
2703
base_branch, path = Branch.open_containing(branch)
2704
branch1 = revision[1].get_branch() or branch
2705
other_branch, path1 = Branch.open_containing(branch1)
2706
if revision[0].get_branch() is not None:
2707
# then path was obtained from it, and is None.
2710
base = [branch, revision[0].in_history(base_branch).revno]
2711
other = [branch1, revision[1].in_history(other_branch).revno]
2810
pb = ui.ui_factory.nested_progress_bar()
2811
cleanups.append(pb.finished)
2813
cleanups.append(tree.unlock)
2814
if location is not None:
2815
mergeable, other_transport = _get_mergeable_helper(location)
2818
raise errors.BzrCommandError('Cannot use --uncommitted'
2819
' with bundles or merge directives.')
2821
if revision is not None:
2822
raise errors.BzrCommandError(
2823
'Cannot use -r with merge directives or bundles')
2824
merger, verified = _mod_merge.Merger.from_mergeable(tree,
2826
possible_transports.append(other_transport)
2828
if merger is None and uncommitted:
2829
if revision is not None and len(revision) > 0:
2830
raise errors.BzrCommandError('Cannot use --uncommitted and'
2831
' --revision at the same time.')
2832
location = self._select_branch_location(tree, location)[0]
2833
other_tree, other_path = WorkingTree.open_containing(location)
2834
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
2836
allow_pending = False
2837
if other_path != '':
2838
merger.interesting_files = [other_path]
2841
merger, allow_pending = self._get_merger_from_branch(tree,
2842
location, revision, remember, possible_transports, pb)
2844
merger.merge_type = merge_type
2845
merger.reprocess = reprocess
2846
merger.show_base = show_base
2847
merger.change_reporter = change_reporter
2848
self.sanity_check_merger(merger)
2849
if (merger.base_rev_id == merger.other_rev_id and
2850
merger.other_rev_id != None):
2851
note('Nothing to do.')
2854
if merger.interesting_files is not None:
2855
raise errors.BzrCommandError('Cannot pull individual files')
2856
if (merger.base_rev_id == tree.last_revision()):
2857
result = tree.pull(merger.other_branch, False,
2858
merger.other_rev_id)
2859
result.report(self.outf)
2861
merger.check_basis(not force)
2862
conflict_count = merger.do_merge()
2864
merger.set_pending()
2865
if verified == 'failed':
2866
warning('Preview patch does not match changes')
2867
if conflict_count != 0:
2872
for cleanup in reversed(cleanups):
2875
def sanity_check_merger(self, merger):
2876
if (merger.show_base and
2877
not merger.merge_type is _mod_merge.Merge3Merger):
2878
raise errors.BzrCommandError("Show-base is not supported for this"
2879
" merge type. %s" % merger.merge_type)
2880
if merger.reprocess and not merger.merge_type.supports_reprocess:
2881
raise errors.BzrCommandError("Conflict reduction is not supported"
2882
" for merge type %s." %
2884
if merger.reprocess and merger.show_base:
2885
raise errors.BzrCommandError("Cannot do conflict reduction and"
2888
def _get_merger_from_branch(self, tree, location, revision, remember,
2889
possible_transports, pb):
2890
"""Produce a merger from a location, assuming it refers to a branch."""
2891
from bzrlib.tag import _merge_tags_if_possible
2892
assert revision is None or len(revision) < 3
2893
# find the branch locations
2894
other_loc, location = self._select_branch_location(tree, location,
2896
if revision is not None and len(revision) == 2:
2897
base_loc, location = self._select_branch_location(tree, location,
2900
base_loc = other_loc
2902
other_branch, other_path = Branch.open_containing(other_loc,
2903
possible_transports)
2904
if base_loc == other_loc:
2905
base_branch = other_branch
2907
base_branch, base_path = Branch.open_containing(base_loc,
2908
possible_transports)
2909
# Find the revision ids
2910
if revision is None or len(revision) < 1 or revision[-1] is None:
2911
other_revision_id = _mod_revision.ensure_null(
2912
other_branch.last_revision())
2914
other_revision_id = \
2915
_mod_revision.ensure_null(
2916
revision[-1].in_history(other_branch).rev_id)
2917
if (revision is not None and len(revision) == 2
2918
and revision[0] is not None):
2919
base_revision_id = \
2920
_mod_revision.ensure_null(
2921
revision[0].in_history(base_branch).rev_id)
2923
base_revision_id = None
2924
# Remember where we merge from
2713
2925
if ((tree.branch.get_parent() is None or remember) and
2714
2926
other_branch is not None):
2715
2927
tree.branch.set_parent(other_branch.base)
2717
# pull tags now... it's a bit inconsistent to do it ahead of copying
2718
# the history but that's done inside the merge code
2719
if other_branch is not None:
2720
_merge_tags_if_possible(other_branch, tree.branch)
2723
interesting_files = [path]
2928
_merge_tags_if_possible(other_branch, tree.branch)
2929
merger = _mod_merge.Merger.from_revision_ids(pb, tree,
2930
other_revision_id, base_revision_id, other_branch, base_branch)
2931
if other_path != '':
2932
allow_pending = False
2933
merger.interesting_files = [other_path]
2725
interesting_files = None
2726
pb = ui.ui_factory.nested_progress_bar()
2729
conflict_count = _merge_helper(
2730
other, base, other_rev_id=other_revision_id,
2731
check_clean=(not force),
2732
merge_type=merge_type,
2733
reprocess=reprocess,
2734
show_base=show_base,
2737
pb=pb, file_list=interesting_files,
2738
change_reporter=change_reporter)
2741
if conflict_count != 0:
2745
except errors.AmbiguousBase, e:
2746
m = ("sorry, bzr can't determine the right merge base yet\n"
2747
"candidates are:\n "
2748
+ "\n ".join(e.bases)
2750
"please specify an explicit base with -r,\n"
2751
"and (if you want) report this to the bzr developers\n")
2935
allow_pending = True
2936
return merger, allow_pending
2938
def _select_branch_location(self, tree, location, revision=None,
2940
"""Select a branch location, according to possible inputs.
2942
If provided, branches from ``revision`` are preferred. (Both
2943
``revision`` and ``index`` must be supplied.)
2945
Otherwise, the ``location`` parameter is used. If it is None, then the
2946
``parent`` location is used, and a note is printed.
2948
:param tree: The working tree to select a branch for merging into
2949
:param location: The location entered by the user
2950
:param revision: The revision parameter to the command
2951
:param index: The index to use for the revision parameter. Negative
2952
indices are permitted.
2953
:return: (selected_location, default_location). The default location
2954
will be the user-entered location, if any, or else the remembered
2957
if (revision is not None and index is not None
2958
and revision[index] is not None):
2959
branch = revision[index].get_branch()
2960
if branch is not None:
2961
return branch, location
2962
location = self._get_remembered_parent(tree, location, 'Merging from')
2963
return location, location
2754
2965
# TODO: move up to common parent; this isn't merge-specific anymore.
2755
2966
def _get_remembered_parent(self, tree, supplied_location, verb_string):
3060
3307
return status_code
3310
class cmd_pack(Command):
3311
"""Compress the data within a repository."""
3313
_see_also = ['repositories']
3314
takes_args = ['branch_or_repo?']
3316
def run(self, branch_or_repo='.'):
3317
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3319
branch = dir.open_branch()
3320
repository = branch.repository
3321
except errors.NotBranchError:
3322
repository = dir.open_repository()
3063
3326
class cmd_plugins(Command):
3327
"""List the installed plugins.
3329
This command displays the list of installed plugins including the
3330
path where each one is located and a short description of each.
3332
A plugin is an external component for Bazaar that extends the
3333
revision control system, by adding or replacing code in Bazaar.
3334
Plugins can do a variety of things, including overriding commands,
3335
adding new commands, providing additional network transports and
3336
customizing log output.
3338
See the Bazaar web site, http://bazaar-vcs.org, for further
3339
information on plugins including where to find them and how to
3340
install them. Instructions are also provided there on how to
3341
write new plugins using the Python programming language.
3066
3344
@display_command
3068
3346
import bzrlib.plugin
3069
3347
from inspect import getdoc
3070
for name, plugin in bzrlib.plugin.all_plugins().items():
3071
if getattr(plugin, '__path__', None) is not None:
3072
print plugin.__path__[0]
3073
elif getattr(plugin, '__file__', None) is not None:
3074
print plugin.__file__
3348
for name, plugin in bzrlib.plugin.plugins().items():
3349
print plugin.path(), "[%s]" % plugin.__version__
3350
d = getdoc(plugin.module)
3080
3352
print '\t', d.split('\n')[0]
3083
3355
class cmd_testament(Command):
3084
3356
"""Show testament (signing-form) of a revision."""
3085
takes_options = ['revision',
3086
Option('long', help='Produce long-format testament'),
3087
Option('strict', help='Produce a strict-format'
3359
Option('long', help='Produce long-format testament.'),
3361
help='Produce a strict-format testament.')]
3089
3362
takes_args = ['branch?']
3090
3363
@display_command
3091
3364
def run(self, branch=u'.', revision=None, long=False, strict=False):
3526
3852
takes_args = ['submit_branch?', 'public_branch?']
3856
_see_also = ['send']
3528
3858
takes_options = [
3529
3859
RegistryOption.from_kwargs('patch-type',
3530
'The type of patch to include in the directive',
3531
title='Patch type', value_switches=True, enum_switch=False,
3532
bundle='Bazaar revision bundle (default)',
3533
diff='Normal unified diff',
3534
plain='No patch, just directive'),
3535
Option('sign', help='GPG-sign the directive'), 'revision',
3860
'The type of patch to include in the directive.',
3862
value_switches=True,
3864
bundle='Bazaar revision bundle (default).',
3865
diff='Normal unified diff.',
3866
plain='No patch, just directive.'),
3867
Option('sign', help='GPG-sign the directive.'), 'revision',
3536
3868
Option('mail-to', type=str,
3537
help='Instead of printing the directive, email to this address'),
3869
help='Instead of printing the directive, email to this address.'),
3538
3870
Option('message', type=str, short_name='m',
3539
help='Message to use when committing this merge')
3871
help='Message to use when committing this merge.')
3874
encoding_type = 'exact'
3542
3876
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3543
3877
sign=False, revision=None, mail_to=None, message=None):
3544
if patch_type == 'plain':
3878
from bzrlib.revision import ensure_null, NULL_REVISION
3879
include_patch, include_bundle = {
3880
'plain': (False, False),
3881
'diff': (True, False),
3882
'bundle': (True, True),
3546
3884
branch = Branch.open('.')
3547
3885
stored_submit_branch = branch.get_submit_branch()
3548
3886
if submit_branch is None:
3583
3928
self.outf.writelines(directive.to_lines())
3585
3930
message = directive.to_email(mail_to, branch, sign)
3587
server = branch.get_config().get_user_option('smtp_server')
3589
server = 'localhost'
3591
s.sendmail(message['From'], message['To'], message.as_string())
3931
s = SMTPConnection(branch.get_config())
3932
s.send_email(message)
3935
class cmd_send(Command):
3936
"""Mail or create a merge-directive for submiting changes.
3938
A merge directive provides many things needed for requesting merges:
3940
* A machine-readable description of the merge to perform
3942
* An optional patch that is a preview of the changes requested
3944
* An optional bundle of revision data, so that the changes can be applied
3945
directly from the merge directive, without retrieving data from a
3948
If --no-bundle is specified, then public_branch is needed (and must be
3949
up-to-date), so that the receiver can perform the merge using the
3950
public_branch. The public_branch is always included if known, so that
3951
people can check it later.
3953
The submit branch defaults to the parent, but can be overridden. Both
3954
submit branch and public branch will be remembered if supplied.
3956
If a public_branch is known for the submit_branch, that public submit
3957
branch is used in the merge instructions. This means that a local mirror
3958
can be used as your actual submit branch, once you have set public_branch
3961
Mail is sent using your preferred mail program. This should be transparent
3962
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
3963
If the preferred client can't be found (or used), your editor will be used.
3965
To use a specific mail program, set the mail_client configuration option.
3966
(For Thunderbird 1.5, this works around some bugs.) Supported values for
3967
specific clients are "evolution", "kmail", "mutt", and "thunderbird";
3968
generic options are "default", "editor", "mapi", and "xdg-email".
3970
If mail is being sent, a to address is required. This can be supplied
3971
either on the commandline, or by setting the submit_to configuration
3974
Two formats are currently supported: "4" uses revision bundle format 4 and
3975
merge directive format 2. It is significantly faster and smaller than
3976
older formats. It is compatible with Bazaar 0.19 and later. It is the
3977
default. "0.9" uses revision bundle format 0.9 and merge directive
3978
format 1. It is compatible with Bazaar 0.12 - 0.18.
3981
encoding_type = 'exact'
3983
_see_also = ['merge']
3985
takes_args = ['submit_branch?', 'public_branch?']
3989
help='Do not include a bundle in the merge directive.'),
3990
Option('no-patch', help='Do not include a preview patch in the merge'
3993
help='Remember submit and public branch.'),
3995
help='Branch to generate the submission from, '
3996
'rather than the one containing the working directory.',
3999
Option('output', short_name='o', help='Write directive to this file.',
4001
Option('mail-to', help='Mail the request to this address.',
4005
RegistryOption.from_kwargs('format',
4006
'Use the specified output format.',
4007
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4008
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4011
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4012
no_patch=False, revision=None, remember=False, output=None,
4013
format='4', mail_to=None, message=None, **kwargs):
4014
return self._run(submit_branch, revision, public_branch, remember,
4015
format, no_bundle, no_patch, output,
4016
kwargs.get('from', '.'), mail_to, message)
4018
def _run(self, submit_branch, revision, public_branch, remember, format,
4019
no_bundle, no_patch, output, from_, mail_to, message):
4020
from bzrlib.revision import NULL_REVISION
4021
branch = Branch.open_containing(from_)[0]
4023
outfile = StringIO()
4027
outfile = open(output, 'wb')
4028
# we may need to write data into branch's repository to calculate
4033
config = branch.get_config()
4035
mail_to = config.get_user_option('submit_to')
4036
mail_client = config.get_mail_client()
4037
if remember and submit_branch is None:
4038
raise errors.BzrCommandError(
4039
'--remember requires a branch to be specified.')
4040
stored_submit_branch = branch.get_submit_branch()
4041
remembered_submit_branch = False
4042
if submit_branch is None:
4043
submit_branch = stored_submit_branch
4044
remembered_submit_branch = True
4046
if stored_submit_branch is None or remember:
4047
branch.set_submit_branch(submit_branch)
4048
if submit_branch is None:
4049
submit_branch = branch.get_parent()
4050
remembered_submit_branch = True
4051
if submit_branch is None:
4052
raise errors.BzrCommandError('No submit branch known or'
4054
if remembered_submit_branch:
4055
note('Using saved location: %s', submit_branch)
4057
stored_public_branch = branch.get_public_branch()
4058
if public_branch is None:
4059
public_branch = stored_public_branch
4060
elif stored_public_branch is None or remember:
4061
branch.set_public_branch(public_branch)
4062
if no_bundle and public_branch is None:
4063
raise errors.BzrCommandError('No public branch specified or'
4065
base_revision_id = None
4067
if revision is not None:
4068
if len(revision) > 2:
4069
raise errors.BzrCommandError('bzr send takes '
4070
'at most two one revision identifiers')
4071
revision_id = revision[-1].in_history(branch).rev_id
4072
if len(revision) == 2:
4073
base_revision_id = revision[0].in_history(branch).rev_id
4074
if revision_id is None:
4075
revision_id = branch.last_revision()
4076
if revision_id == NULL_REVISION:
4077
raise errors.BzrCommandError('No revisions to submit.')
4079
directive = merge_directive.MergeDirective2.from_objects(
4080
branch.repository, revision_id, time.time(),
4081
osutils.local_time_offset(), submit_branch,
4082
public_branch=public_branch, include_patch=not no_patch,
4083
include_bundle=not no_bundle, message=message,
4084
base_revision_id=base_revision_id)
4085
elif format == '0.9':
4088
patch_type = 'bundle'
4090
raise errors.BzrCommandError('Format 0.9 does not'
4091
' permit bundle with no patch')
4097
directive = merge_directive.MergeDirective.from_objects(
4098
branch.repository, revision_id, time.time(),
4099
osutils.local_time_offset(), submit_branch,
4100
public_branch=public_branch, patch_type=patch_type,
4103
outfile.writelines(directive.to_lines())
4105
subject = '[MERGE] '
4106
if message is not None:
4109
revision = branch.repository.get_revision(revision_id)
4110
subject += revision.get_summary()
4111
mail_client.compose_merge_request(mail_to, subject,
4119
class cmd_bundle_revisions(cmd_send):
4121
"""Create a merge-directive for submiting changes.
4123
A merge directive provides many things needed for requesting merges:
4125
* A machine-readable description of the merge to perform
4127
* An optional patch that is a preview of the changes requested
4129
* An optional bundle of revision data, so that the changes can be applied
4130
directly from the merge directive, without retrieving data from a
4133
If --no-bundle is specified, then public_branch is needed (and must be
4134
up-to-date), so that the receiver can perform the merge using the
4135
public_branch. The public_branch is always included if known, so that
4136
people can check it later.
4138
The submit branch defaults to the parent, but can be overridden. Both
4139
submit branch and public branch will be remembered if supplied.
4141
If a public_branch is known for the submit_branch, that public submit
4142
branch is used in the merge instructions. This means that a local mirror
4143
can be used as your actual submit branch, once you have set public_branch
4146
Two formats are currently supported: "4" uses revision bundle format 4 and
4147
merge directive format 2. It is significantly faster and smaller than
4148
older formats. It is compatible with Bazaar 0.19 and later. It is the
4149
default. "0.9" uses revision bundle format 0.9 and merge directive
4150
format 1. It is compatible with Bazaar 0.12 - 0.18.
4155
help='Do not include a bundle in the merge directive.'),
4156
Option('no-patch', help='Do not include a preview patch in the merge'
4159
help='Remember submit and public branch.'),
4161
help='Branch to generate the submission from, '
4162
'rather than the one containing the working directory.',
4165
Option('output', short_name='o', help='Write directive to this file.',
4168
RegistryOption.from_kwargs('format',
4169
'Use the specified output format.',
4170
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4171
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4173
aliases = ['bundle']
4175
_see_also = ['send', 'merge']
4179
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4180
no_patch=False, revision=None, remember=False, output=None,
4181
format='4', **kwargs):
4184
return self._run(submit_branch, revision, public_branch, remember,
4185
format, no_bundle, no_patch, output,
4186
kwargs.get('from', '.'), None, None)
3594
4189
class cmd_tag(Command):
3595
"""Create a tag naming a revision.
4190
"""Create, remove or modify a tag naming a revision.
3597
4192
Tags give human-meaningful names to revisions. Commands that take a -r
3598
4193
(--revision) option can be given -rtag:X, where X is any previously
3654
4249
class cmd_tags(Command):
3657
This tag shows a table of tag names and the revisions they reference.
4252
This command shows a table of tag names and the revisions they reference.
3660
4255
_see_also = ['tag']
3661
4256
takes_options = [
3662
4257
Option('directory',
3663
help='Branch whose tags should be displayed',
4258
help='Branch whose tags should be displayed.',
3664
4259
short_name='d',
4262
RegistryOption.from_kwargs('sort',
4263
'Sort tags by different criteria.', title='Sorting',
4264
alpha='Sort tags lexicographically (default).',
4265
time='Sort tags chronologically.',
3669
4270
@display_command
3673
4276
branch, relpath = Branch.open_containing(directory)
3674
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3675
self.outf.write('%-20s %s\n' % (tag_name, target))
3678
# command-line interpretation helper for merge-related commands
3679
def _merge_helper(other_revision, base_revision,
3680
check_clean=True, ignore_zero=False,
3681
this_dir=None, backup_files=False,
3683
file_list=None, show_base=False, reprocess=False,
3686
change_reporter=None,
3688
"""Merge changes into a tree.
3691
list(path, revno) Base for three-way merge.
3692
If [None, None] then a base will be automatically determined.
3694
list(path, revno) Other revision for three-way merge.
3696
Directory to merge changes into; '.' by default.
3698
If true, this_dir must have no uncommitted changes before the
3700
ignore_zero - If true, suppress the "zero conflicts" message when
3701
there are no conflicts; should be set when doing something we expect
3702
to complete perfectly.
3703
file_list - If supplied, merge only changes to selected files.
3705
All available ancestors of other_revision and base_revision are
3706
automatically pulled into the branch.
3708
The revno may be -1 to indicate the last revision on the branch, which is
3711
This function is intended for use from the command line; programmatic
3712
clients might prefer to call merge.merge_inner(), which has less magic
3715
# Loading it late, so that we don't always have to import bzrlib.merge
3716
if merge_type is None:
3717
merge_type = _mod_merge.Merge3Merger
3718
if this_dir is None:
3720
this_tree = WorkingTree.open_containing(this_dir)[0]
3721
if show_base and not merge_type is _mod_merge.Merge3Merger:
3722
raise errors.BzrCommandError("Show-base is not supported for this merge"
3723
" type. %s" % merge_type)
3724
if reprocess and not merge_type.supports_reprocess:
3725
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3726
" type %s." % merge_type)
3727
if reprocess and show_base:
3728
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3729
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3730
# only want to take out a lock_tree_write() if we don't have to pull
3731
# any ancestry. But merge might fetch ancestry in the middle, in
3732
# which case we would need a lock_write().
3733
# Because we cannot upgrade locks, for now we live with the fact that
3734
# the tree will be locked multiple times during a merge. (Maybe
3735
# read-only some of the time, but it means things will get read
3738
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3739
pb=pb, change_reporter=change_reporter)
3740
merger.pp = ProgressPhase("Merge phase", 5, pb)
3741
merger.pp.next_phase()
3742
merger.check_basis(check_clean)
3743
if other_rev_id is not None:
3744
merger.set_other_revision(other_rev_id, this_tree.branch)
3746
merger.set_other(other_revision)
3747
merger.pp.next_phase()
3748
merger.set_base(base_revision)
3749
if merger.base_rev_id == merger.other_rev_id:
3750
note('Nothing to do.')
3752
if file_list is None:
3753
if pull and merger.base_rev_id == merger.this_rev_id:
3754
# FIXME: deduplicate with pull
3755
result = merger.this_tree.pull(merger.this_branch,
3756
False, merger.other_rev_id)
3757
if result.old_revid == result.new_revid:
3758
note('No revisions to pull.')
4277
tags = branch.tags.get_tag_dict().items()
4280
elif sort == 'time':
4282
for tag, revid in tags:
4284
revobj = branch.repository.get_revision(revid)
4285
except errors.NoSuchRevision:
4286
timestamp = sys.maxint # place them at the end
3760
note('Now on revision %d.' % result.new_revno)
3762
merger.backup_files = backup_files
3763
merger.merge_type = merge_type
3764
merger.set_interesting_files(file_list)
3765
merger.show_base = show_base
3766
merger.reprocess = reprocess
3767
conflicts = merger.do_merge()
3768
if file_list is None:
3769
merger.set_pending()
4288
timestamp = revobj.timestamp
4289
timestamps[revid] = timestamp
4290
tags.sort(key=lambda x: timestamps[x[1]])
4292
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
4293
revno_map = branch.get_revision_id_to_revno_map()
4294
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
4295
for tag, revid in tags ]
4296
for tag, revspec in tags:
4297
self.outf.write('%-20s %s\n' % (tag, revspec))
4300
class cmd_reconfigure(Command):
4301
"""Reconfigure the type of a bzr directory.
4303
A target configuration must be specified.
4305
For checkouts, the bind-to location will be auto-detected if not specified.
4306
The order of preference is
4307
1. For a lightweight checkout, the current bound location.
4308
2. For branches that used to be checkouts, the previously-bound location.
4309
3. The push location.
4310
4. The parent location.
4311
If none of these is available, --bind-to must be specified.
4314
takes_args = ['location?']
4315
takes_options = [RegistryOption.from_kwargs('target_type',
4316
title='Target type',
4317
help='The type to reconfigure the directory to.',
4318
value_switches=True, enum_switch=False,
4319
branch='Reconfigure to a branch.',
4320
tree='Reconfigure to a tree.',
4321
checkout='Reconfigure to a checkout.',
4322
lightweight_checkout='Reconfigure to a lightweight'
4324
Option('bind-to', help='Branch to bind checkout to.',
4327
help='Perform reconfiguration even if local changes'
4331
def run(self, location=None, target_type=None, bind_to=None, force=False):
4332
directory = bzrdir.BzrDir.open(location)
4333
if target_type is None:
4334
raise errors.BzrCommandError('No target configuration specified')
4335
elif target_type == 'branch':
4336
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
4337
elif target_type == 'tree':
4338
reconfiguration = reconfigure.Reconfigure.to_tree(directory)
4339
elif target_type == 'checkout':
4340
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4342
elif target_type == 'lightweight-checkout':
4343
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4345
reconfiguration.apply(force)
4348
class cmd_switch(Command):
4349
"""Set the branch of a checkout and update.
4351
For lightweight checkouts, this changes the branch being referenced.
4352
For heavyweight checkouts, this checks that there are no local commits
4353
versus the current bound branch, then it makes the local branch a mirror
4354
of the new location and binds to it.
4356
In both cases, the working tree is updated and uncommitted changes
4357
are merged. The user can commit or revert these as they desire.
4359
Pending merges need to be committed or reverted before using switch.
4362
takes_args = ['to_location']
4363
takes_options = [Option('force',
4364
help='Switch even if local commits will be lost.')
4367
def run(self, to_location, force=False):
4368
from bzrlib import switch
4369
to_branch = Branch.open(to_location)
4371
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4372
switch.switch(control_dir, to_branch, force)
4373
note('Switched to branch: %s',
4374
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
3775
4377
def _create_prefix(cur_transport):