15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
# TODO: Split the command framework away from the actual commands.
20
# TODO: probably should say which arguments are candidates for glob
21
# expansion on windows and do that at the command level.
23
# TODO: Help messages for options.
25
# TODO: Define arguments by objects, rather than just using names.
26
# Those objects can specify the expected type of the argument, which
27
# would help with validation and shell completion.
30
# TODO: Help messages for options.
32
# TODO: Define arguments by objects, rather than just using names.
33
# Those objects can specify the expected type of the argument, which
34
# would help with validation and shell completion.
22
42
from bzrlib.trace import mutter, note, log_error, warning
23
43
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
24
44
from bzrlib.branch import find_branch
136
157
raise BzrCommandError(msg)
160
def get_merge_type(typestring):
161
"""Attempt to find the merge class/factory associated with a string."""
162
from merge import merge_types
164
return merge_types[typestring][0]
166
templ = '%s%%7s: %%s' % (' '*12)
167
lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
168
type_list = '\n'.join(lines)
169
msg = "No known merge type %s. Supported types are:\n%s" %\
170
(typestring, type_list)
171
raise BzrCommandError(msg)
140
175
def _get_cmd_dict(plugins_override=True):
237
273
class ExternalCommand(Command):
238
274
"""Class to wrap external commands.
240
We cheat a little here, when get_cmd_class() calls us we actually give it back
241
an object we construct that has the appropriate path, help, options etc for the
244
When run_bzr() tries to instantiate that 'class' it gets caught by the __call__
245
method, which we override to call the Command.__init__ method. That then calls
246
our run method which is pretty straight forward.
248
The only wrinkle is that we have to map bzr's dictionary of options and arguments
249
back into command line options and arguments for the script.
276
We cheat a little here, when get_cmd_class() calls us we actually
277
give it back an object we construct that has the appropriate path,
278
help, options etc for the specified command.
280
When run_bzr() tries to instantiate that 'class' it gets caught by
281
the __call__ method, which we override to call the Command.__init__
282
method. That then calls our run method which is pretty straight
285
The only wrinkle is that we have to map bzr's dictionary of options
286
and arguments back into command line options and arguments for the
252
290
def find_command(cls, cmd):
438
476
takes_options = ['verbose', 'no-recurse']
440
478
def run(self, file_list, verbose=False, no_recurse=False):
441
from bzrlib.add import smart_add
442
smart_add(file_list, verbose, not no_recurse)
479
from bzrlib.add import smart_add, _PrintAddCallback
480
recurse = not no_recurse
481
smart_add(file_list, verbose, not no_recurse,
482
callback=_PrintAddCallback)
573
class cmd_mv(Command):
574
"""Move or rename a file.
577
bzr mv OLDNAME NEWNAME
578
bzr mv SOURCE... DESTINATION
580
If the last argument is a versioned directory, all the other names
581
are moved into it. Otherwise, there must be exactly two arguments
582
and the file is changed to a new name, which must not already exist.
584
Files cannot be moved between branches.
586
takes_args = ['names*']
587
def run(self, names_list):
588
if len(names_list) < 2:
589
raise BzrCommandError("missing file argument")
590
b = find_branch(names_list[0])
592
rel_names = [b.relpath(x) for x in names_list]
594
if os.path.isdir(names_list[-1]):
595
# move into existing directory
596
for pair in b.move(rel_names[:-1], rel_names[-1]):
597
print "%s => %s" % pair
599
if len(names_list) != 2:
600
raise BzrCommandError('to mv multiple files the destination '
601
'must be a versioned directory')
602
for pair in b.move(rel_names[0], rel_names[1]):
603
print "%s => %s" % pair
533
608
class cmd_pull(Command):
601
677
takes_args = ['from_location', 'to_location?']
602
678
takes_options = ['revision']
679
aliases = ['get', 'clone']
604
681
def run(self, from_location, to_location=None, revision=None):
682
from bzrlib.branch import copy_branch, find_cached_branch
606
from bzrlib.merge import merge
607
from bzrlib.branch import DivergedBranches, NoSuchRevision, \
608
find_cached_branch, Branch
609
685
from shutil import rmtree
610
from meta_store import CachedStore
612
686
cache_root = tempfile.mkdtemp()
616
elif len(revision) > 1:
617
raise BzrCommandError('bzr branch --revision takes exactly 1 revision value')
690
elif len(revision) > 1:
691
raise BzrCommandError(
692
'bzr branch --revision takes exactly 1 revision value')
621
694
br_from = find_cached_branch(from_location, cache_root)
622
695
except OSError, e:
643
br_to = Branch(to_location, init=True)
645
br_to.set_root_id(br_from.get_root_id())
648
if revision[0] is None:
649
revno = br_from.revno()
651
revno, rev_id = br_from.get_revision_info(revision[0])
653
br_to.update_revisions(br_from, stop_revision=revno)
654
except NoSuchRevision:
656
msg = "The branch %s has no revision %d." % (from_location,
658
raise BzrCommandError(msg)
660
merge((to_location, -1), (to_location, 0), this_dir=to_location,
661
check_clean=False, ignore_zero=True)
662
from_location = pull_loc(br_from)
663
br_to.controlfile("x-pull", "wb").write(from_location + "\n")
715
copy_branch(br_from, to_location, revision[0])
716
except bzrlib.errors.NoSuchRevision:
718
msg = "The branch %s has no revision %d." % (from_location, revision[0])
719
raise BzrCommandError(msg)
665
721
rmtree(cache_root)
668
def pull_loc(branch):
669
# TODO: Should perhaps just make attribute be 'base' in
670
# RemoteBranch and Branch?
671
if hasattr(branch, "baseurl"):
672
return branch.baseurl
678
724
class cmd_renames(Command):
679
725
"""Show list of renamed files.
832
881
b = find_branch('.')
834
# TODO: Make show_diff support taking 2 arguments
836
883
if revision is not None:
837
if len(revision) != 1:
838
raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
839
base_rev = revision[0]
841
show_diff(b, base_rev, specific_files=file_list,
842
external_diff_options=diff_options)
884
if len(revision) == 1:
885
show_diff(b, revision[0], specific_files=file_list,
886
external_diff_options=diff_options)
887
elif len(revision) == 2:
888
show_diff(b, revision[0], specific_files=file_list,
889
external_diff_options=diff_options,
890
revision2=revision[1])
892
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
894
show_diff(b, None, specific_files=file_list,
895
external_diff_options=diff_options)
929
981
takes_args = ['filename?']
930
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
982
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
983
'long', 'message', 'short',]
932
985
def run(self, filename=None, timezone='original',
1311
1373
takes_options = ['email']
1313
1375
def run(self, email=False):
1377
b = bzrlib.branch.find_branch('.')
1315
print bzrlib.osutils.user_email()
1382
print bzrlib.osutils.user_email(b)
1317
print bzrlib.osutils.username()
1384
print bzrlib.osutils.username(b)
1320
1387
class cmd_selftest(Command):
1321
1388
"""Run internal test suite"""
1323
takes_options = ['verbose']
1324
def run(self, verbose=False):
1390
takes_options = ['verbose', 'pattern']
1391
def run(self, verbose=False, pattern=".*"):
1325
1393
from bzrlib.selftest import selftest
1326
return int(not selftest(verbose=verbose))
1394
# we don't want progress meters from the tests to go to the
1395
# real output; and we don't want log messages cluttering up
1397
save_ui = bzrlib.ui.ui_factory
1398
bzrlib.trace.info('running tests...')
1400
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1401
result = selftest(verbose=verbose, pattern=pattern)
1403
bzrlib.trace.info('tests passed')
1405
bzrlib.trace.info('tests failed')
1406
return int(not result)
1408
bzrlib.ui.ui_factory = save_ui
1329
1411
class cmd_version(Command):
1469
class cmd_find_merge_base(Command):
1470
"""Find and print a base revision for merging two branches.
1472
TODO: Options to specify revisions on either side, as if
1473
merging only part of the history.
1475
takes_args = ['branch', 'other']
1478
def run(self, branch, other):
1479
branch1 = find_branch(branch)
1480
branch2 = find_branch(other)
1482
base_revno, base_revid = branch1.common_ancestor(branch2)
1484
if base_revno is None:
1485
raise bzrlib.errors.UnrelatedBranches()
1487
print 'merge base is revision %s' % base_revid
1488
print ' r%-6d in %s' % (base_revno, branch)
1490
other_revno = branch2.revision_id_to_revno(base_revid)
1492
print ' r%-6d in %s' % (other_revno, other)
1387
1496
class cmd_merge(Command):
1388
"""Perform a three-way merge of trees.
1390
The SPEC parameters are working tree or revision specifiers. Working trees
1391
are specified using standard paths or urls. No component of a directory
1392
path may begin with '@'.
1394
Working tree examples: '.', '..', 'foo@', but NOT 'foo/@bar'
1396
Revisions are specified using a dirname/@revno pair, where dirname is the
1397
branch directory and revno is the revision within that branch. If no revno
1398
is specified, the latest revision is used.
1400
Revision examples: './@127', 'foo/@', '../@1'
1402
The OTHER_SPEC parameter is required. If the BASE_SPEC parameter is
1403
not supplied, the common ancestor of OTHER_SPEC the current branch is used
1497
"""Perform a three-way merge.
1499
The branch is the branch you will merge from. By default, it will merge
1500
the latest revision. If you specify a revision, that revision will be
1501
merged. If you specify two revisions, the first will be used as a BASE,
1502
and the second one as OTHER. Revision numbers are always relative to the
1507
To merge the latest revision from bzr.dev
1508
bzr merge ../bzr.dev
1510
To merge changes up to and including revision 82 from bzr.dev
1511
bzr merge -r 82 ../bzr.dev
1513
To merge the changes introduced by 82, without previous changes:
1514
bzr merge -r 81..82 ../bzr.dev
1406
1516
merge refuses to run if there are any uncommitted changes, unless
1407
1517
--force is given.
1409
takes_args = ['other_spec', 'base_spec?']
1410
takes_options = ['force', 'merge-type']
1519
takes_args = ['branch?']
1520
takes_options = ['revision', 'force', 'merge-type']
1412
def run(self, other_spec, base_spec=None, force=False, merge_type=None):
1522
def run(self, branch='.', revision=None, force=False,
1413
1524
from bzrlib.merge import merge
1414
1525
from bzrlib.merge_core import ApplyMerge3
1415
1526
if merge_type is None:
1416
1527
merge_type = ApplyMerge3
1417
merge(parse_spec(other_spec), parse_spec(base_spec),
1418
check_clean=(not force), merge_type=merge_type)
1529
if revision is None or len(revision) < 1:
1531
other = (branch, -1)
1533
if len(revision) == 1:
1534
other = (branch, revision[0])
1537
assert len(revision) == 2
1538
if None in revision:
1539
raise BzrCommandError(
1540
"Merge doesn't permit that revision specifier.")
1541
base = (branch, revision[0])
1542
other = (branch, revision[1])
1544
merge(other, base, check_clean=(not force), merge_type=merge_type)
1421
1547
class cmd_revert(Command):
1456
1585
"""Show help on a command or other topic.
1458
1587
For a list of all available commands, say 'bzr help commands'."""
1588
takes_options = ['long']
1459
1589
takes_args = ['topic?']
1460
1590
aliases = ['?']
1462
def run(self, topic=None):
1592
def run(self, topic=None, long=False):
1594
if topic is None and long:
1464
1596
help.help(topic)
1599
class cmd_shell_complete(Command):
1600
"""Show appropriate completions for context.
1602
For a list of all available commands, say 'bzr shell-complete'."""
1603
takes_args = ['context?']
1607
def run(self, context=None):
1608
import shellcomplete
1609
shellcomplete.shellcomplete(context)
1612
class cmd_missing(Command):
1613
"""What is missing in this branch relative to other branch.
1615
takes_args = ['remote?']
1616
aliases = ['mis', 'miss']
1617
# We don't have to add quiet to the list, because
1618
# unknown options are parsed as booleans
1619
takes_options = ['verbose', 'quiet']
1621
def run(self, remote=None, verbose=False, quiet=False):
1622
from bzrlib.branch import find_branch, DivergedBranches
1623
from bzrlib.errors import BzrCommandError
1624
from bzrlib.missing import get_parent, show_missing
1626
if verbose and quiet:
1627
raise BzrCommandError('Cannot pass both quiet and verbose')
1629
b = find_branch('.')
1630
parent = get_parent(b)
1633
raise BzrCommandError("No missing location known or specified.")
1636
print "Using last location: %s" % parent
1638
elif parent is None:
1639
# We only update x-pull if it did not exist, missing should not change the parent
1640
b.controlfile('x-pull', 'wb').write(remote + '\n')
1641
br_remote = find_branch(remote)
1643
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1469
1647
class cmd_plugins(Command):
1667
def _parse_master_args(argv):
1668
"""Parse the arguments that always go with the original command.
1669
These are things like bzr --no-plugins, etc.
1671
There are now 2 types of option flags. Ones that come *before* the command,
1672
and ones that come *after* the command.
1673
Ones coming *before* the command are applied against all possible commands.
1674
And are generally applied before plugins are loaded.
1676
The current list are:
1677
--builtin Allow plugins to load, but don't let them override builtin commands,
1678
they will still be allowed if they do not override a builtin.
1679
--no-plugins Don't load any plugins. This lets you get back to official source
1681
--profile Enable the hotspot profile before running the command.
1682
For backwards compatibility, this is also a non-master option.
1683
--version Spit out the version of bzr that is running and exit.
1684
This is also a non-master option.
1685
--help Run help and exit, also a non-master option (I think that should stay, though)
1687
>>> argv, opts = _parse_master_args(['--test'])
1688
Traceback (most recent call last):
1690
BzrCommandError: Invalid master option: 'test'
1691
>>> argv, opts = _parse_master_args(['--version', 'command'])
1694
>>> print opts['version']
1696
>>> argv, opts = _parse_master_args(['--profile', 'command', '--more-options'])
1698
['command', '--more-options']
1699
>>> print opts['profile']
1701
>>> argv, opts = _parse_master_args(['--no-plugins', 'command'])
1704
>>> print opts['no-plugins']
1706
>>> print opts['profile']
1708
>>> argv, opts = _parse_master_args(['command', '--profile'])
1710
['command', '--profile']
1711
>>> print opts['profile']
1714
master_opts = {'builtin':False,
1722
if arg[:2] != '--': # at the first non-option, we return the rest
1724
arg = arg[2:] # Remove '--'
1725
if arg not in master_opts:
1726
# We could say that this is not an error, that we should
1727
# just let it be handled by the main section instead
1728
raise BzrCommandError('Invalid master option: %r' % arg)
1729
argv.pop(0) # We are consuming this entry
1730
master_opts[arg] = True
1731
return argv, master_opts
1735
1851
def run_bzr(argv):
1736
1852
"""Execute a command.
1739
1855
logging and error handling.
1742
The command-line arguments, without the program name.
1858
The command-line arguments, without the program name from argv[0]
1744
1860
Returns a command status or raises an exception.
1862
Special master options: these must come before the command because
1863
they control how the command is interpreted.
1866
Do not load plugin modules at all
1869
Only use builtin commands. (Plugins are still allowed to change
1873
Run under the Python profiler.
1746
1876
argv = [a.decode(bzrlib.user_encoding) for a in argv]
1748
# some options like --builtin and --no-plugins have special effects
1749
argv, master_opts = _parse_master_args(argv)
1750
if not master_opts['no-plugins']:
1878
opt_profile = opt_no_plugins = opt_builtin = False
1880
# --no-plugins is handled specially at a very early stage. We need
1881
# to load plugins before doing other command parsing so that they
1882
# can override commands, but this needs to happen first.
1885
if a == '--profile':
1887
elif a == '--no-plugins':
1888
opt_no_plugins = True
1889
elif a == '--builtin':
1895
if not opt_no_plugins:
1751
1896
from bzrlib.plugin import load_plugins
1754
1899
args, opts = parse_args(argv)
1756
if master_opts.get('help') or 'help' in opts:
1757
1902
from bzrlib.help import help
1768
if args and args[0] == 'builtin':
1769
include_plugins=False
1914
from bzrlib.help import help
1773
cmd = str(args.pop(0))
1775
print >>sys.stderr, "please try 'bzr help' for help"
1778
plugins_override = not (master_opts['builtin'])
1779
canonical_cmd, cmd_class = get_cmd_class(cmd, plugins_override=plugins_override)
1781
profile = master_opts['profile']
1782
# For backwards compatibility, I would rather stick with --profile being a
1783
# master/global option
1784
if 'profile' in opts:
1918
cmd = str(args.pop(0))
1920
canonical_cmd, cmd_class = \
1921
get_cmd_class(cmd, plugins_override=not opt_builtin)
1788
1923
# check options are reasonable
1789
1924
allowed = cmd_class.takes_options
1823
1958
return cmd_class(cmdopts, cmdargs).status
1826
def _report_exception(summary, quiet=False):
1828
log_error('bzr: ' + summary)
1829
bzrlib.trace.log_exception()
1832
tb = sys.exc_info()[2]
1833
exinfo = traceback.extract_tb(tb)
1835
sys.stderr.write(' at %s:%d in %s()\n' % exinfo[-1][:3])
1836
sys.stderr.write(' see ~/.bzr.log for debug information\n')
1840
1961
def main(argv):
1842
bzrlib.trace.open_tracefile(argv)
1963
bzrlib.trace.log_startup(argv)
1964
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1847
return run_bzr(argv[1:])
1849
# do this here inside the exception wrappers to catch EPIPE
1852
quiet = isinstance(e, (BzrCommandError))
1853
_report_exception('error: ' + e.args[0], quiet=quiet)
1856
# some explanation or hints
1859
except AssertionError, e:
1860
msg = 'assertion failed'
1862
msg += ': ' + str(e)
1863
_report_exception(msg)
1865
except KeyboardInterrupt, e:
1866
_report_exception('interrupted', quiet=True)
1868
except Exception, e:
1871
if (isinstance(e, IOError)
1872
and hasattr(e, 'errno')
1873
and e.errno == errno.EPIPE):
1877
msg = str(e).rstrip('\n')
1878
_report_exception(msg, quiet)
1881
bzrlib.trace.close_trace()
1968
return run_bzr(argv[1:])
1970
# do this here inside the exception wrappers to catch EPIPE
1972
except BzrCommandError, e:
1973
# command line syntax error, etc
1977
bzrlib.trace.log_exception()
1979
except AssertionError, e:
1980
bzrlib.trace.log_exception('assertion failed: ' + str(e))
1982
except KeyboardInterrupt, e:
1983
bzrlib.trace.note('interrupted')
1985
except Exception, e:
1987
if (isinstance(e, IOError)
1988
and hasattr(e, 'errno')
1989
and e.errno == errno.EPIPE):
1990
bzrlib.trace.note('broken pipe')
1993
bzrlib.trace.log_exception()
1884
1997
if __name__ == '__main__':