186
169
takes_args = ['file*']
187
170
takes_options = ['show-ids', 'revision',
188
Option('short', help='Give short SVN-style status lines'),
189
Option('versioned', help='Only show versioned files')]
171
Option('short', help='Give short SVN-style status lines.'),
172
Option('versioned', help='Only show versioned files.')]
190
173
aliases = ['st', 'stat']
192
175
encoding_type = 'replace'
193
_see_also = ['diff', 'revert']
176
_see_also = ['diff', 'revert', 'status-flags']
196
179
def run(self, show_ids=False, file_list=None, revision=None, short=False,
669
672
location can be accessed.
672
_see_also = ['pull', 'update']
675
_see_also = ['pull', 'update', 'working-trees']
673
676
takes_options = ['remember', 'overwrite', 'verbose',
674
677
Option('create-prefix',
675
678
help='Create the path leading up to the branch '
676
'if it does not already exist'),
679
'if it does not already exist.'),
677
680
Option('directory',
678
help='branch to push from, '
679
'rather than the one containing the working directory',
681
help='Branch to push from, '
682
'rather than the one containing the working directory.',
683
686
Option('use-existing-dir',
684
687
help='By default push will fail if the target'
685
688
' directory exists, but does not already'
686
' have a control directory. This flag will'
689
' have a control directory. This flag will'
687
690
' allow push to proceed.'),
689
692
takes_args = ['location?']
750
754
"\nYou may supply --create-prefix to create all"
751
755
" leading parent directories."
754
cur_transport = to_transport
755
needed = [cur_transport]
756
# Recurse upwards until we can create a directory successfully
758
new_transport = cur_transport.clone('..')
759
if new_transport.base == cur_transport.base:
760
raise errors.BzrCommandError("Failed to create path"
764
new_transport.mkdir('.')
765
except errors.NoSuchFile:
766
needed.append(new_transport)
767
cur_transport = new_transport
771
# Now we only need to create child directories
773
cur_transport = needed.pop()
774
cur_transport.ensure_base()
757
_create_prefix(to_transport)
776
759
# Now the target directory exists, but doesn't have a .bzr
777
760
# directory. So we need to create it, along with any work to create
807
790
# we don't need to successfully push because of possible divergence.
808
791
if br_from.get_push_location() is None or remember:
809
792
br_from.set_push_location(br_to.base)
810
old_rh = br_to.revision_history()
794
old_rh = br_to.revision_history()
813
797
tree_to = dir_to.open_workingtree()
814
798
except errors.NotLocalUrl:
815
warning('This transport does not update the working '
816
'tree of: %s' % (br_to.base,))
799
warning("This transport does not update the working "
800
"tree of: %s. See 'bzr help working-trees' for "
801
"more information." % br_to.base)
817
802
push_result = br_from.push(br_to, overwrite)
818
803
except errors.NoWorkingTree:
819
804
push_result = br_from.push(br_to, overwrite)
1030
1024
tree.lock_tree_write()
1032
1026
existing_pending_merges = tree.get_parent_ids()[1:]
1033
last_rev = tree.last_revision()
1034
if last_rev == tree.branch.last_revision():
1027
last_rev = _mod_revision.ensure_null(tree.last_revision())
1028
if last_rev == _mod_revision.ensure_null(
1029
tree.branch.last_revision()):
1035
1030
# may be up to date, check master too.
1036
1031
master = tree.branch.get_master_branch()
1037
if master is None or last_rev == master.last_revision():
1032
if master is None or last_rev == _mod_revision.ensure_null(
1033
master.last_revision()):
1038
1034
revno = tree.branch.revision_id_to_revno(last_rev)
1039
1035
note("Tree is up to date at revision %d." % (revno,))
1041
conflicts = tree.update()
1042
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1037
conflicts = tree.update(delta._ChangeReporter(
1038
unversioned_filter=tree.is_ignored))
1039
revno = tree.branch.revision_id_to_revno(
1040
_mod_revision.ensure_null(tree.last_revision()))
1043
1041
note('Updated to revision %d.' % (revno,))
1044
1042
if tree.get_parent_ids()[1:] != existing_pending_merges:
1045
1043
note('Your local commits will now show as pending merges with '
1282
1284
# Just using os.mkdir, since I don't
1283
1285
# believe that we want to create a bunch of
1284
1286
# locations if the user supplies an extended path
1285
# TODO: create-prefix
1286
to_transport.ensure_base()
1288
to_transport.ensure_base()
1289
except errors.NoSuchFile:
1290
if not create_prefix:
1291
raise errors.BzrCommandError("Parent directory of %s"
1293
"\nYou may supply --create-prefix to create all"
1294
" leading parent directories."
1296
_create_prefix(to_transport)
1289
# FIXME: Reuse to_transport instead of location
1290
existing_bzrdir = bzrdir.BzrDir.open(location)
1299
existing_bzrdir = bzrdir.BzrDir.open_from_transport(to_transport)
1291
1300
except errors.NotBranchError:
1292
1301
# really a NotBzrDir error...
1293
# FIXME: Reuse to_transport instead of
1294
# to_transport.base (nastier than above)
1295
branch = bzrdir.BzrDir.create_branch_convenience(to_transport.base,
1302
create_branch = bzrdir.BzrDir.create_branch_convenience
1303
branch = create_branch(to_transport.base, format=format,
1304
possible_transports=[to_transport])
1298
1306
from bzrlib.transport.local import LocalTransport
1299
1307
if existing_bzrdir.has_branch():
1324
1335
bzr checkout --lightweight repo/trunk trunk-checkout
1325
1336
cd trunk-checkout
1326
1337
(add files here)
1339
See 'bzr help repositories' for more information.
1329
1342
_see_also = ['init', 'branch', 'checkout']
1330
1343
takes_args = ["location"]
1331
1344
takes_options = [RegistryOption('format',
1332
1345
help='Specify a format for this repository. See'
1333
' "bzr help formats" for details',
1346
' "bzr help formats" for details.',
1334
1347
registry=bzrdir.format_registry,
1335
1348
converter=bzrdir.format_registry.make_bzrdir,
1336
1349
value_switches=True, title='Repository format'),
1337
1350
Option('no-trees',
1338
1351
help='Branches in the repository will default to'
1339
' not having a working tree'),
1352
' not having a working tree.'),
1341
1354
aliases = ["init-repo"]
1578
1602
# TODO: Make --revision support uuid: and hash: [future tag:] notation.
1580
1604
takes_args = ['location?']
1581
takes_options = [Option('forward',
1582
help='show from oldest to newest'),
1586
help='show files changed in each revision'),
1587
'show-ids', 'revision',
1591
help='show revisions whose message matches this regexp',
1607
help='Show from oldest to newest.'),
1610
help='Display timezone as local, original, or utc.'),
1613
help='Show files changed in each revision.'),
1619
help='Show revisions whose message matches this '
1620
'regular expression.',
1623
help='Limit the output to the first N revisions.',
1594
1627
encoding_type = 'replace'
1596
1629
@display_command
1647
1681
raise errors.BzrCommandError(
1648
1682
"Log doesn't accept two revisions in different"
1650
if revision[0].spec is None:
1651
# missing begin-range means first revision
1654
rev1 = revision[0].in_history(b).revno
1656
if revision[1].spec is None:
1657
# missing end-range means last known revision
1660
rev2 = revision[1].in_history(b).revno
1684
rev1 = revision[0].in_history(b)
1685
rev2 = revision[1].in_history(b)
1662
1687
raise errors.BzrCommandError(
1663
1688
'bzr log --revision takes one or two values.')
1665
# By this point, the revision numbers are converted to the +ve
1666
# form if they were supplied in the -ve form, so we can do
1667
# this comparison in relative safety
1669
(rev2, rev1) = (rev1, rev2)
1671
1690
if log_format is None:
1672
1691
log_format = log.log_formatter_registry.get_default(b)
1722
1742
_see_also = ['status', 'cat']
1723
1743
takes_args = ['path?']
1724
1744
# TODO: Take a revision or remote path and list that tree instead.
1725
takes_options = ['verbose', 'revision',
1726
Option('non-recursive',
1727
help='don\'t recurse into sub-directories'),
1729
help='Print all paths from the root of the branch.'),
1730
Option('unknown', help='Print unknown files'),
1731
Option('versioned', help='Print versioned files'),
1732
Option('ignored', help='Print ignored files'),
1734
Option('null', help='Null separate the files'),
1748
Option('non-recursive',
1749
help='Don\'t recurse into subdirectories.'),
1751
help='Print paths relative to the root of the branch.'),
1752
Option('unknown', help='Print unknown files.'),
1753
Option('versioned', help='Print versioned files.'),
1754
Option('ignored', help='Print ignored files.'),
1756
help='Write an ascii NUL (\\0) separator '
1757
'between files rather than a newline.'),
1759
help='List entries of a particular kind: file, directory, symlink.',
1737
1763
@display_command
1738
def run(self, revision=None, verbose=False,
1764
def run(self, revision=None, verbose=False,
1739
1765
non_recursive=False, from_root=False,
1740
1766
unknown=False, versioned=False, ignored=False,
1741
1767
null=False, kind=None, show_ids=False, path=None):
2102
2139
_see_also = ['bugs', 'uncommit']
2103
2140
takes_args = ['selected*']
2104
takes_options = ['message', 'verbose',
2106
help='commit even if nothing has changed'),
2107
Option('file', type=str,
2110
help='file containing commit message'),
2112
help="refuse to commit if there are unknown "
2113
"files in the working tree."),
2114
ListOption('fixes', type=str,
2115
help="mark a bug as being fixed by this "
2118
help="perform a local only commit in a bound "
2119
"branch. Such commits are not pushed to "
2120
"the master branch until a normal commit "
2142
Option('message', type=unicode,
2144
help="Description of the new revision."),
2147
help='Commit even if nothing has changed.'),
2148
Option('file', type=str,
2151
help='Take commit message from this file.'),
2153
help="Refuse to commit if there are unknown "
2154
"files in the working tree."),
2155
ListOption('fixes', type=str,
2156
help="Mark a bug as being fixed by this revision."),
2158
help="Perform a local commit in a bound "
2159
"branch. Local commits are not pushed to "
2160
"the master branch until a normal commit "
2124
2164
aliases = ['ci', 'checkin']
2126
2166
def _get_bug_fix_properties(self, fixes, branch):
2372
2407
modified by plugins will not be tested, and tests provided by plugins will
2410
Tests that need working space on disk use a common temporary directory,
2411
typically inside $TMPDIR or /tmp.
2376
2414
bzr selftest ignore
2377
2415
run only tests relating to 'ignore'
2378
2416
bzr --no-plugins selftest -v
2379
2417
disable plugins and list tests as they're run
2381
For each test, that needs actual disk access, bzr create their own
2382
subdirectory in the temporary testing directory (testXXXX.tmp).
2383
By default the name of such subdirectory is based on the name of the test.
2384
If option '--numbered-dirs' is given, bzr will use sequent numbers
2385
of running tests to create such subdirectories. This is default behavior
2386
on Windows because of path length limitation.
2388
2419
# NB: this is used from the class without creating an instance, which is
2389
2420
# why it does not have a self parameter.
2406
2437
takes_args = ['testspecs*']
2407
2438
takes_options = ['verbose',
2409
help='stop when one test fails',
2440
help='Stop when one test fails.',
2410
2441
short_name='1',
2412
Option('keep-output',
2413
help='keep output directories when tests fail'),
2414
2443
Option('transport',
2415
2444
help='Use a different transport by default '
2416
2445
'throughout the test suite.',
2417
2446
type=get_transport_type),
2418
Option('benchmark', help='run the bzr benchmarks.'),
2448
help='Run the benchmarks rather than selftests.'),
2419
2449
Option('lsprof-timed',
2420
help='generate lsprof output for benchmarked'
2450
help='Generate lsprof output for benchmarked'
2421
2451
' sections of code.'),
2422
2452
Option('cache-dir', type=str,
2423
help='a directory to cache intermediate'
2424
' benchmark steps'),
2425
Option('clean-output',
2426
help='clean temporary tests directories'
2427
' without running tests'),
2453
help='Cache intermediate benchmark output in this '
2428
2455
Option('first',
2429
help='run all tests, but run specified tests first',
2456
help='Run all tests, but run specified tests first.',
2430
2457
short_name='f',
2432
Option('numbered-dirs',
2433
help='use numbered dirs for TestCaseInTempDir'),
2434
2459
Option('list-only',
2435
help='list the tests instead of running them'),
2460
help='List the tests instead of running them.'),
2436
2461
Option('randomize', type=str, argname="SEED",
2437
help='randomize the order of tests using the given'
2438
' seed or "now" for the current time'),
2462
help='Randomize the order of tests using the given'
2463
' seed or "now" for the current time.'),
2439
2464
Option('exclude', type=str, argname="PATTERN",
2440
2465
short_name='x',
2441
help='exclude tests that match this regular'
2466
help='Exclude tests that match this regular'
2444
2469
encoding_type = 'replace'
2446
2471
def run(self, testspecs_list=None, verbose=None, one=False,
2447
keep_output=False, transport=None, benchmark=None,
2448
lsprof_timed=None, cache_dir=None, clean_output=False,
2449
first=False, numbered_dirs=None, list_only=False,
2472
transport=None, benchmark=None,
2473
lsprof_timed=None, cache_dir=None,
2474
first=False, list_only=False,
2450
2475
randomize=None, exclude=None):
2451
2476
import bzrlib.ui
2452
2477
from bzrlib.tests import selftest
2453
2478
import bzrlib.benchmarks as benchmarks
2454
2479
from bzrlib.benchmarks import tree_creator
2457
from bzrlib.tests import clean_selftest_output
2458
clean_selftest_output()
2461
if numbered_dirs is None and sys.platform == 'win32':
2462
numbered_dirs = True
2480
from bzrlib.version import show_version
2464
2482
if cache_dir is not None:
2465
2483
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2466
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2467
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2485
show_version(show_config=False, show_copyright=False)
2469
2487
if testspecs_list is not None:
2470
2488
pattern = '|'.join(testspecs_list)
2535
2551
@display_command
2536
2552
def run(self, branch, other):
2537
from bzrlib.revision import MultipleRevisionSources
2553
from bzrlib.revision import ensure_null, MultipleRevisionSources
2539
2555
branch1 = Branch.open_containing(branch)[0]
2540
2556
branch2 = Branch.open_containing(other)[0]
2542
last1 = branch1.last_revision()
2543
last2 = branch2.last_revision()
2558
last1 = ensure_null(branch1.last_revision())
2559
last2 = ensure_null(branch2.last_revision())
2545
source = MultipleRevisionSources(branch1.repository,
2548
base_rev_id = common_ancestor(last1, last2, source)
2561
graph = branch1.repository.get_graph(branch2.repository)
2562
base_rev_id = graph.find_unique_lca(last1, last2)
2550
2564
print 'merge base is revision %s' % base_rev_id
2594
2608
--force is given.
2597
_see_also = ['update', 'remerge']
2611
_see_also = ['update', 'remerge', 'status-flags']
2598
2612
takes_args = ['branch?']
2599
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2616
help='Merge even if the destination tree has uncommitted changes.'),
2600
2620
Option('show-base', help="Show base revision text in "
2602
2622
Option('uncommitted', help='Apply uncommitted changes'
2603
' from a working copy, instead of branch changes'),
2623
' from a working copy, instead of branch changes.'),
2604
2624
Option('pull', help='If the destination is already'
2605
2625
' completely merged into the source, pull from the'
2606
' source rather than merging. When this happens,'
2626
' source rather than merging. When this happens,'
2607
2627
' you do not need to commit the result.'),
2608
2628
Option('directory',
2609
help='Branch to merge into, '
2610
'rather than the one containing the working directory',
2629
help='Branch to merge into, '
2630
'rather than the one containing the working directory.',
2616
2636
def run(self, branch=None, revision=None, force=False, merge_type=None,
2635
2654
change_reporter = delta._ChangeReporter(
2636
2655
unversioned_filter=tree.is_ignored)
2657
other_transport = None
2658
other_revision_id = None
2659
base_revision_id = None
2660
possible_transports = []
2638
2662
if branch is not None:
2640
mergeable = bundle.read_mergeable_from_url(
2642
except errors.NotABundle:
2643
pass # Continue on considering this url a Branch
2663
mergeable, other_transport = _get_bundle_helper(branch)
2645
2665
if revision is not None:
2646
2666
raise errors.BzrCommandError(
2647
2667
'Cannot use -r with merge directives or bundles')
2648
other_revision_id = mergeable.install_revisions(
2649
tree.branch.repository)
2650
revision = [RevisionSpec.from_string(
2651
'revid:' + other_revision_id)]
2653
if revision is None \
2654
or len(revision) < 1 or revision[0].needs_branch():
2655
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2657
if revision is None or len(revision) < 1:
2660
other = [branch, None]
2668
mergeable.install_revisions(tree.branch.repository)
2669
base_revision_id, other_revision_id, verified =\
2670
mergeable.get_merge_request(tree.branch.repository)
2671
if base_revision_id in tree.branch.repository.get_ancestry(
2672
tree.branch.last_revision(), topo_sorted=False):
2673
base_revision_id = None
2678
possible_transports.append(other_transport)
2680
if other_revision_id is None:
2681
verified = 'inapplicable'
2682
if revision is None \
2683
or len(revision) < 1 or revision[0].needs_branch():
2684
branch = self._get_remembered_parent(tree, branch,
2687
if revision is None or len(revision) < 1:
2690
other = [branch, None]
2693
other = [branch, -1]
2694
other_branch, path = Branch.open_containing(branch,
2695
possible_transports)
2663
other = [branch, -1]
2664
other_branch, path = Branch.open_containing(branch)
2667
raise errors.BzrCommandError('Cannot use --uncommitted and'
2668
' --revision at the same time.')
2669
branch = revision[0].get_branch() or branch
2670
if len(revision) == 1:
2672
if other_revision_id is not None:
2677
other_branch, path = Branch.open_containing(branch)
2698
raise errors.BzrCommandError('Cannot use --uncommitted and'
2699
' --revision at the same time.')
2700
branch = revision[0].get_branch() or branch
2701
if len(revision) == 1:
2703
other_branch, path = Branch.open_containing(
2704
branch, possible_transports)
2678
2705
revno = revision[0].in_history(other_branch).revno
2679
2706
other = [branch, revno]
2681
assert len(revision) == 2
2682
if None in revision:
2683
raise errors.BzrCommandError(
2684
"Merge doesn't permit empty revision specifier.")
2685
base_branch, path = Branch.open_containing(branch)
2686
branch1 = revision[1].get_branch() or branch
2687
other_branch, path1 = Branch.open_containing(branch1)
2688
if revision[0].get_branch() is not None:
2689
# then path was obtained from it, and is None.
2692
base = [branch, revision[0].in_history(base_branch).revno]
2693
other = [branch1, revision[1].in_history(other_branch).revno]
2708
assert len(revision) == 2
2709
if None in revision:
2710
raise errors.BzrCommandError(
2711
"Merge doesn't permit empty revision specifier.")
2712
base_branch, path = Branch.open_containing(
2713
branch, possible_transports)
2714
branch1 = revision[1].get_branch() or branch
2715
other_branch, path1 = Branch.open_containing(
2716
branch1, possible_transports)
2717
if revision[0].get_branch() is not None:
2718
# then path was obtained from it, and is None.
2721
base = [branch, revision[0].in_history(base_branch).revno]
2723
revision[1].in_history(other_branch).revno]
2725
# Remember where we merge from
2695
2726
if ((tree.branch.get_parent() is None or remember) and
2696
2727
other_branch is not None):
2697
2728
tree.branch.set_parent(other_branch.base)
2823
2861
restore(tree.abspath(filename))
2824
2862
except errors.NotConflicted:
2826
conflicts = _mod_merge.merge_inner(
2827
tree.branch, other_tree, base_tree,
2829
interesting_ids=interesting_ids,
2830
other_rev_id=parents[1],
2831
merge_type=merge_type,
2832
show_base=show_base,
2833
reprocess=reprocess)
2864
# Disable pending merges, because the file texts we are remerging
2865
# have not had those merges performed. If we use the wrong parents
2866
# list, we imply that the working tree text has seen and rejected
2867
# all the changes from the other tree, when in fact those changes
2868
# have not yet been seen.
2869
tree.set_parent_ids(parents[:1])
2871
conflicts = _mod_merge.merge_inner(
2872
tree.branch, other_tree, base_tree,
2874
interesting_ids=interesting_ids,
2875
other_rev_id=parents[1],
2876
merge_type=merge_type,
2877
show_base=show_base,
2878
reprocess=reprocess)
2880
tree.set_parent_ids(parents)
2836
2883
if conflicts > 0:
2948
3000
class cmd_missing(Command):
2949
3001
"""Show unmerged/unpulled revisions between two branches.
2951
3003
OTHER_BRANCH may be local or remote.
2954
3006
_see_also = ['merge', 'pull']
2955
3007
takes_args = ['other_branch?']
2956
takes_options = [Option('reverse', 'Reverse the order of revisions'),
2958
'Display changes in the local branch only'),
2959
Option('theirs-only',
2960
'Display changes in the remote branch only'),
3009
Option('reverse', 'Reverse the order of revisions.'),
3011
'Display changes in the local branch only.'),
3012
Option('this' , 'Same as --mine-only.'),
3013
Option('theirs-only',
3014
'Display changes in the remote branch only.'),
3015
Option('other', 'Same as --theirs-only.'),
2965
3020
encoding_type = 'replace'
2967
3022
@display_command
2968
3023
def run(self, other_branch=None, reverse=False, mine_only=False,
2969
3024
theirs_only=False, log_format=None, long=False, short=False, line=False,
2970
show_ids=False, verbose=False):
2971
from bzrlib.missing import find_unmerged, iter_log_data
3025
show_ids=False, verbose=False, this=False, other=False):
3026
from bzrlib.missing import find_unmerged, iter_log_revisions
2972
3027
from bzrlib.log import log_formatter
2973
3034
local_branch = Branch.open_containing(u".")[0]
2974
3035
parent = local_branch.get_parent()
2975
3036
if other_branch is None:
2976
3037
other_branch = parent
2977
3038
if other_branch is None:
2978
raise errors.BzrCommandError("No peer location known or specified.")
3039
raise errors.BzrCommandError("No peer location known"
2979
3041
display_url = urlutils.unescape_for_display(parent,
2980
3042
self.outf.encoding)
2981
print "Using last location: " + display_url
3043
self.outf.write("Using last location: " + display_url + "\n")
2983
3045
remote_branch = Branch.open(other_branch)
2984
3046
if remote_branch.base == local_branch.base:
2998
3061
local_extra.reverse()
2999
3062
remote_extra.reverse()
3000
3063
if local_extra and not theirs_only:
3001
print "You have %d extra revision(s):" % len(local_extra)
3002
for data in iter_log_data(local_extra, local_branch.repository,
3064
self.outf.write("You have %d extra revision(s):\n" %
3066
for revision in iter_log_revisions(local_extra,
3067
local_branch.repository,
3069
lf.log_revision(revision)
3005
3070
printed_local = True
3007
3072
printed_local = False
3008
3073
if remote_extra and not mine_only:
3009
3074
if printed_local is True:
3011
print "You are missing %d revision(s):" % len(remote_extra)
3012
for data in iter_log_data(remote_extra, remote_branch.repository,
3075
self.outf.write("\n\n\n")
3076
self.outf.write("You are missing %d revision(s):\n" %
3078
for revision in iter_log_revisions(remote_extra,
3079
remote_branch.repository,
3081
lf.log_revision(revision)
3015
3082
if not remote_extra and not local_extra:
3016
3083
status_code = 0
3017
print "Branches are up to date."
3084
self.outf.write("Branches are up to date.\n")
3019
3086
status_code = 1
3032
3099
return status_code
3102
class cmd_pack(Command):
3103
"""Compress the data within a repository."""
3105
_see_also = ['repositories']
3106
takes_args = ['branch_or_repo?']
3108
def run(self, branch_or_repo='.'):
3109
dir = bzrdir.BzrDir.open_containing(branch_or_repo)[0]
3111
branch = dir.open_branch()
3112
repository = branch.repository
3113
except errors.NotBranchError:
3114
repository = dir.open_repository()
3035
3118
class cmd_plugins(Command):
3119
"""List the installed plugins.
3121
This command displays the list of installed plugins including the
3122
path where each one is located and a short description of each.
3124
A plugin is an external component for Bazaar that extends the
3125
revision control system, by adding or replacing code in Bazaar.
3126
Plugins can do a variety of things, including overriding commands,
3127
adding new commands, providing additional network transports and
3128
customizing log output.
3130
See the Bazaar web site, http://bazaar-vcs.org, for further
3131
information on plugins including where to find them and how to
3132
install them. Instructions are also provided there on how to
3133
write new plugins using the Python programming language.
3038
3136
@display_command
3040
3138
import bzrlib.plugin
3341
3443
takes_options = [
3343
help='serve on stdin/out for use from inetd or sshd'),
3445
help='Serve on stdin/out for use from inetd or sshd.'),
3345
help='listen for connections on nominated port of the form '
3346
'[hostname:]portnumber. Passing 0 as the port number will '
3347
'result in a dynamically allocated port. Default port is '
3447
help='Listen for connections on nominated port of the form '
3448
'[hostname:]portnumber. Passing 0 as the port number will '
3449
'result in a dynamically allocated port. The default port is '
3350
3452
Option('directory',
3351
help='serve contents of directory',
3453
help='Serve contents of this directory.',
3353
3455
Option('allow-writes',
3354
help='By default the server is a readonly server. Supplying '
3456
help='By default the server is a readonly server. Supplying '
3355
3457
'--allow-writes enables write access to the contents of '
3356
'the served directory and below. '
3458
'the served directory and below.'
3498
3602
takes_args = ['submit_branch?', 'public_branch?']
3606
_see_also = ['submit']
3500
3608
takes_options = [
3501
3609
RegistryOption.from_kwargs('patch-type',
3502
3610
'The type of patch to include in the directive',
3503
title='Patch type', value_switches=True, enum_switch=False,
3504
bundle='Bazaar revision bundle (default)',
3505
diff='Normal unified diff',
3506
plain='No patch, just directive'),
3507
Option('sign', help='GPG-sign the directive'), 'revision',
3612
value_switches=True,
3614
bundle='Bazaar revision bundle (default).',
3615
diff='Normal unified diff.',
3616
plain='No patch, just directive.'),
3617
Option('sign', help='GPG-sign the directive.'), 'revision',
3508
3618
Option('mail-to', type=str,
3509
help='Instead of printing the directive, email to this address'),
3619
help='Instead of printing the directive, email to this address.'),
3510
3620
Option('message', type=str, short_name='m',
3511
help='Message to use when committing this merge')
3621
help='Message to use when committing this merge.')
3624
encoding_type = 'exact'
3514
3626
def run(self, submit_branch=None, public_branch=None, patch_type='bundle',
3515
3627
sign=False, revision=None, mail_to=None, message=None):
3516
if patch_type == 'plain':
3628
from bzrlib.revision import ensure_null, NULL_REVISION
3629
include_patch, include_bundle = {
3630
'plain': (False, False),
3631
'diff': (True, False),
3632
'bundle': (True, True),
3518
3634
branch = Branch.open('.')
3519
3635
stored_submit_branch = branch.get_submit_branch()
3520
3636
if submit_branch is None:
3532
3648
public_branch = stored_public_branch
3533
3649
elif stored_public_branch is None:
3534
3650
branch.set_public_branch(public_branch)
3535
if patch_type != "bundle" and public_branch is None:
3651
if not include_bundle and public_branch is None:
3536
3652
raise errors.BzrCommandError('No public branch specified or'
3654
base_revision_id = None
3538
3655
if revision is not None:
3539
if len(revision) != 1:
3656
if len(revision) > 2:
3540
3657
raise errors.BzrCommandError('bzr merge-directive takes '
3541
'exactly one revision identifier')
3543
revision_id = revision[0].in_history(branch).rev_id
3658
'at most two one revision identifiers')
3659
revision_id = revision[-1].in_history(branch).rev_id
3660
if len(revision) == 2:
3661
base_revision_id = revision[0].in_history(branch).rev_id
3662
base_revision_id = ensure_null(base_revision_id)
3545
3664
revision_id = branch.last_revision()
3546
directive = merge_directive.MergeDirective.from_objects(
3665
revision_id = ensure_null(revision_id)
3666
if revision_id == NULL_REVISION:
3667
raise errors.BzrCommandError('No revisions to bundle.')
3668
directive = merge_directive.MergeDirective2.from_objects(
3547
3669
branch.repository, revision_id, time.time(),
3548
3670
osutils.local_time_offset(), submit_branch,
3549
public_branch=public_branch, patch_type=patch_type,
3671
public_branch=public_branch, include_patch=include_patch,
3672
include_bundle=include_bundle, message=message,
3673
base_revision_id=base_revision_id)
3551
3674
if mail_to is None:
3553
3676
self.outf.write(directive.to_signed(branch))
3555
3678
self.outf.writelines(directive.to_lines())
3557
3680
message = directive.to_email(mail_to, branch, sign)
3559
server = branch.get_config().get_user_option('smtp_server')
3561
server = 'localhost'
3563
s.sendmail(message['From'], message['To'], message.as_string())
3681
s = SMTPConnection(branch.get_config())
3682
s.send_email(message)
3685
class cmd_submit(Command):
3686
"""Create a merge-directive for submiting changes.
3688
A merge directive provides many things needed for requesting merges:
3689
- A machine-readable description of the merge to perform
3690
- An optional patch that is a preview of the changes requested
3691
- An optional bundle of revision data, so that the changes can be applied
3692
directly from the merge directive, without retrieving data from a
3695
If --no-bundle is specified, then public_branch is needed (and must be
3696
up-to-date), so that the receiver can perform the merge using the
3697
public_branch. The public_branch is always included if known, so that
3698
people can check it later.
3700
The submit branch defaults to the parent, but can be overridden. Both
3701
submit branch and public branch will be remembered if supplied.
3703
If a public_branch is known for the submit_branch, that public submit
3704
branch is used in the merge instructions. This means that a local mirror
3705
can be used as your actual submit branch, once you have set public_branch
3709
encoding_type = 'exact'
3711
aliases = ['bundle', 'bundle-revisions']
3713
_see_also = ['merge']
3715
takes_args = ['submit_branch?', 'public_branch?']
3718
help='Do not include a bundle in the merge directive.'),
3719
Option('no-patch', help='Do not include a preview patch in the merge'
3722
help='Remember submit and public branch.'),
3724
help='Branch to generate the submission from, '
3725
'rather than the one containing the working directory.',
3728
Option('output', short_name='o', help='Write directive to this file.',
3733
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
3734
no_patch=False, revision=None, remember=False, output=None,
3736
from bzrlib.revision import ensure_null, NULL_REVISION
3740
outfile = open(output, 'wb')
3742
from_ = kwargs.get('from', '.')
3743
branch = Branch.open_containing(from_)[0]
3744
if remember and submit_branch is None:
3745
raise errors.BzrCommandError(
3746
'--remember requires a branch to be specified.')
3747
stored_submit_branch = branch.get_submit_branch()
3748
remembered_submit_branch = False
3749
if submit_branch is None:
3750
submit_branch = stored_submit_branch
3751
remembered_submit_branch = True
3753
if stored_submit_branch is None or remember:
3754
branch.set_submit_branch(submit_branch)
3755
if submit_branch is None:
3756
submit_branch = branch.get_parent()
3757
remembered_submit_branch = True
3758
if submit_branch is None:
3759
raise errors.BzrCommandError('No submit branch known or'
3761
if remembered_submit_branch:
3762
note('Using saved location: %s', submit_branch)
3764
stored_public_branch = branch.get_public_branch()
3765
if public_branch is None:
3766
public_branch = stored_public_branch
3767
elif stored_public_branch is None or remember:
3768
branch.set_public_branch(public_branch)
3769
if no_bundle and public_branch is None:
3770
raise errors.BzrCommandError('No public branch specified or'
3772
base_revision_id = None
3773
if revision is not None:
3774
if len(revision) > 2:
3775
raise errors.BzrCommandError('bzr submit takes '
3776
'at most two one revision identifiers')
3777
revision_id = revision[-1].in_history(branch).rev_id
3778
if len(revision) == 2:
3779
base_revision_id = revision[0].in_history(branch).rev_id
3780
base_revision_id = ensure_null(base_revision_id)
3782
revision_id = branch.last_revision()
3783
revision_id = ensure_null(revision_id)
3784
if revision_id == NULL_REVISION:
3785
raise errors.BzrCommandError('No revisions to submit.')
3786
directive = merge_directive.MergeDirective2.from_objects(
3787
branch.repository, revision_id, time.time(),
3788
osutils.local_time_offset(), submit_branch,
3789
public_branch=public_branch, include_patch=not no_patch,
3790
include_bundle=not no_bundle, message=None,
3791
base_revision_id=base_revision_id)
3792
outfile.writelines(directive.to_lines())
3794
if output is not None:
3566
3797
class cmd_tag(Command):
3567
3798
"""Create a tag naming a revision.
3744
3981
return conflicts
3984
def _create_prefix(cur_transport):
3985
needed = [cur_transport]
3986
# Recurse upwards until we can create a directory successfully
3988
new_transport = cur_transport.clone('..')
3989
if new_transport.base == cur_transport.base:
3990
raise errors.BzrCommandError(
3991
"Failed to create path prefix for %s."
3992
% cur_transport.base)
3994
new_transport.mkdir('.')
3995
except errors.NoSuchFile:
3996
needed.append(new_transport)
3997
cur_transport = new_transport
4000
# Now we only need to create child directories
4002
cur_transport = needed.pop()
4003
cur_transport.ensure_base()
4006
def _get_bundle_helper(location):
4007
"""Get a bundle if 'location' points to one.
4009
Try try to identify a bundle and returns its mergeable form. If it's not,
4010
we return the tried transport anyway so that it can reused to access the
4013
:param location: can point to a bundle or a branch.
4015
:return: mergeable, transport
4018
url = urlutils.normalize_url(location)
4019
url, filename = urlutils.split(url, exclude_trailing_slash=False)
4020
location_transport = transport.get_transport(url)
4023
# There may be redirections but we ignore the intermediate
4024
# and final transports used
4025
read = bundle.read_mergeable_from_transport
4026
mergeable, t = read(location_transport, filename)
4027
except errors.NotABundle:
4028
# Continue on considering this url a Branch but adjust the
4029
# location_transport
4030
location_transport = location_transport.clone(filename)
4031
return mergeable, location_transport
3747
4034
# Compatibility
3748
4035
merge = _merge_helper