20
20
# TODO: probably should say which arguments are candidates for glob
21
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.
27
42
from bzrlib.trace import mutter, note, log_error, warning
28
43
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
29
44
from bzrlib.branch import find_branch
141
156
raise BzrCommandError(msg)
159
def get_merge_type(typestring):
160
"""Attempt to find the merge class/factory associated with a string."""
161
from merge import merge_types
163
return merge_types[typestring][0]
165
templ = '%s%%7s: %%s' % (' '*12)
166
lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
167
type_list = '\n'.join(lines)
168
msg = "No known merge type %s. Supported types are:\n%s" %\
169
(typestring, type_list)
170
raise BzrCommandError(msg)
145
174
def _get_cmd_dict(plugins_override=True):
445
474
takes_options = ['verbose', 'no-recurse']
447
476
def run(self, file_list, verbose=False, no_recurse=False):
448
from bzrlib.add import smart_add
449
smart_add(file_list, verbose, not no_recurse)
477
from bzrlib.add import smart_add, _PrintAddCallback
478
smart_add(file_list, verbose, not no_recurse,
479
callback=_PrintAddCallback)
642
673
aliases = ['get', 'clone']
644
675
def run(self, from_location, to_location=None, revision=None):
676
from bzrlib.branch import copy_branch, find_cached_branch
646
from bzrlib.merge import merge
647
from bzrlib.branch import DivergedBranches, \
648
find_cached_branch, Branch
649
679
from shutil import rmtree
650
from meta_store import CachedStore
652
680
cache_root = tempfile.mkdtemp()
656
elif len(revision) > 1:
657
raise BzrCommandError('bzr branch --revision takes exactly 1 revision value')
684
elif len(revision) > 1:
685
raise BzrCommandError(
686
'bzr branch --revision takes exactly 1 revision value')
661
688
br_from = find_cached_branch(from_location, cache_root)
662
689
except OSError, e:
683
br_to = Branch(to_location, init=True)
685
br_to.set_root_id(br_from.get_root_id())
688
if revision[0] is None:
689
revno = br_from.revno()
691
revno, rev_id = br_from.get_revision_info(revision[0])
693
br_to.update_revisions(br_from, stop_revision=revno)
694
except bzrlib.errors.NoSuchRevision:
696
msg = "The branch %s has no revision %d." % (from_location,
698
raise BzrCommandError(msg)
700
merge((to_location, -1), (to_location, 0), this_dir=to_location,
701
check_clean=False, ignore_zero=True)
702
from_location = pull_loc(br_from)
703
br_to.controlfile("x-pull", "wb").write(from_location + "\n")
709
copy_branch(br_from, to_location, revision[0])
710
except bzrlib.errors.NoSuchRevision:
712
msg = "The branch %s has no revision %d." % (from_location, revision[0])
713
raise BzrCommandError(msg)
705
715
rmtree(cache_root)
708
def pull_loc(branch):
709
# TODO: Should perhaps just make attribute be 'base' in
710
# RemoteBranch and Branch?
711
if hasattr(branch, "baseurl"):
712
return branch.baseurl
718
718
class cmd_renames(Command):
719
719
"""Show list of renamed files.
872
875
b = find_branch('.')
874
# TODO: Make show_diff support taking 2 arguments
876
877
if revision is not None:
877
if len(revision) != 1:
878
raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
879
base_rev = revision[0]
881
show_diff(b, base_rev, specific_files=file_list,
882
external_diff_options=diff_options)
878
if len(revision) == 1:
879
show_diff(b, revision[0], specific_files=file_list,
880
external_diff_options=diff_options)
881
elif len(revision) == 2:
882
show_diff(b, revision[0], specific_files=file_list,
883
external_diff_options=diff_options,
884
revision2=revision[1])
886
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
888
show_diff(b, None, specific_files=file_list,
889
external_diff_options=diff_options)
969
975
takes_args = ['filename?']
970
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
976
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
977
'long', 'message', 'short',]
972
979
def run(self, filename=None, timezone='original',
1359
1367
takes_options = ['email']
1361
1369
def run(self, email=False):
1371
b = bzrlib.branch.find_branch('.')
1363
print bzrlib.osutils.user_email()
1376
print bzrlib.osutils.user_email(b)
1365
print bzrlib.osutils.username()
1378
print bzrlib.osutils.username(b)
1368
1381
class cmd_selftest(Command):
1369
1382
"""Run internal test suite"""
1371
takes_options = ['verbose']
1372
def run(self, verbose=False):
1384
takes_options = ['verbose', 'pattern']
1385
def run(self, verbose=False, pattern=".*"):
1373
1387
from bzrlib.selftest import selftest
1374
return int(not selftest(verbose=verbose))
1388
# we don't want progress meters from the tests to go to the
1389
# real output; and we don't want log messages cluttering up
1391
save_ui = bzrlib.ui.ui_factory
1392
bzrlib.trace.info('running tests...')
1393
bzrlib.trace.disable_default_logging()
1395
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1396
result = selftest(verbose=verbose, pattern=pattern)
1398
bzrlib.trace.info('tests passed')
1400
bzrlib.trace.info('tests failed')
1401
return int(not result)
1403
bzrlib.trace.enable_default_logging()
1404
bzrlib.ui.ui_factory = save_ui
1377
1407
class cmd_version(Command):
1465
class cmd_find_merge_base(Command):
1466
"""Find and print a base revision for merging two branches.
1468
TODO: Options to specify revisions on either side, as if
1469
merging only part of the history.
1471
takes_args = ['branch', 'other']
1474
def run(self, branch, other):
1475
branch1 = find_branch(branch)
1476
branch2 = find_branch(other)
1478
base_revno, base_revid = branch1.common_ancestor(branch2)
1480
if base_revno is None:
1481
raise bzrlib.errors.UnrelatedBranches()
1483
print 'merge base is revision %s' % base_revid
1484
print ' r%-6d in %s' % (base_revno, branch)
1486
other_revno = branch2.revision_id_to_revno(base_revid)
1488
print ' r%-6d in %s' % (other_revno, other)
1435
1492
class cmd_merge(Command):
1436
"""Perform a three-way merge of trees.
1438
The SPEC parameters are working tree or revision specifiers. Working trees
1439
are specified using standard paths or urls. No component of a directory
1440
path may begin with '@'.
1442
Working tree examples: '.', '..', 'foo@', but NOT 'foo/@bar'
1444
Revisions are specified using a dirname/@revno pair, where dirname is the
1445
branch directory and revno is the revision within that branch. If no revno
1446
is specified, the latest revision is used.
1448
Revision examples: './@127', 'foo/@', '../@1'
1450
The OTHER_SPEC parameter is required. If the BASE_SPEC parameter is
1451
not supplied, the common ancestor of OTHER_SPEC the current branch is used
1493
"""Perform a three-way merge.
1495
The branch is the branch you will merge from. By default, it will merge
1496
the latest revision. If you specify a revision, that revision will be
1497
merged. If you specify two revisions, the first will be used as a BASE,
1498
and the second one as OTHER. Revision numbers are always relative to the
1503
To merge the latest revision from bzr.dev
1504
bzr merge ../bzr.dev
1506
To merge changes up to and including revision 82 from bzr.dev
1507
bzr merge -r 82 ../bzr.dev
1509
To merge the changes introduced by 82, without previous changes:
1510
bzr merge -r 81..82 ../bzr.dev
1454
1512
merge refuses to run if there are any uncommitted changes, unless
1455
1513
--force is given.
1457
takes_args = ['other_spec', 'base_spec?']
1458
takes_options = ['force', 'merge-type']
1515
takes_args = ['branch?']
1516
takes_options = ['revision', 'force', 'merge-type']
1460
def run(self, other_spec, base_spec=None, force=False, merge_type=None):
1518
def run(self, branch='.', revision=None, force=False,
1461
1520
from bzrlib.merge import merge
1462
1521
from bzrlib.merge_core import ApplyMerge3
1463
1522
if merge_type is None:
1464
1523
merge_type = ApplyMerge3
1465
merge(parse_spec(other_spec), parse_spec(base_spec),
1466
check_clean=(not force), merge_type=merge_type)
1525
if revision is None or len(revision) < 1:
1527
other = (branch, -1)
1529
if len(revision) == 1:
1530
other = (branch, revision[0])
1533
assert len(revision) == 2
1534
if None in revision:
1535
raise BzrCommandError(
1536
"Merge doesn't permit that revision specifier.")
1537
base = (branch, revision[0])
1538
other = (branch, revision[1])
1540
merge(other, base, check_clean=(not force), merge_type=merge_type)
1469
1543
class cmd_revert(Command):
1504
1581
"""Show help on a command or other topic.
1506
1583
For a list of all available commands, say 'bzr help commands'."""
1584
takes_options = ['long']
1507
1585
takes_args = ['topic?']
1508
1586
aliases = ['?']
1510
def run(self, topic=None):
1588
def run(self, topic=None, long=False):
1590
if topic is None and long:
1512
1592
help.help(topic)
1595
class cmd_shell_complete(Command):
1596
"""Show appropriate completions for context.
1598
For a list of all available commands, say 'bzr shell-complete'."""
1599
takes_args = ['context?']
1603
def run(self, context=None):
1604
import shellcomplete
1605
shellcomplete.shellcomplete(context)
1608
class cmd_missing(Command):
1609
"""What is missing in this branch relative to other branch.
1611
takes_args = ['remote?']
1612
aliases = ['mis', 'miss']
1613
# We don't have to add quiet to the list, because
1614
# unknown options are parsed as booleans
1615
takes_options = ['verbose', 'quiet']
1617
def run(self, remote=None, verbose=False, quiet=False):
1618
from bzrlib.branch import find_branch, DivergedBranches
1619
from bzrlib.errors import BzrCommandError
1620
from bzrlib.missing import get_parent, show_missing
1622
if verbose and quiet:
1623
raise BzrCommandError('Cannot pass both quiet and verbose')
1625
b = find_branch('.')
1626
parent = get_parent(b)
1629
raise BzrCommandError("No missing location known or specified.")
1632
print "Using last location: %s" % parent
1634
elif parent is None:
1635
# We only update x-pull if it did not exist, missing should not change the parent
1636
b.controlfile('x-pull', 'wb').write(remote + '\n')
1637
br_remote = find_branch(remote)
1639
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1517
1643
class cmd_plugins(Command):
1822
1951
return cmd_class(cmdopts, cmdargs).status
1825
def _report_exception(summary, quiet=False):
1828
log_error('bzr: ' + summary)
1829
bzrlib.trace.log_exception()
1831
if os.environ.get('BZR_DEBUG'):
1832
traceback.print_exc()
1835
sys.stderr.write('\n')
1836
tb = sys.exc_info()[2]
1837
exinfo = traceback.extract_tb(tb)
1839
sys.stderr.write(' at %s:%d in %s()\n' % exinfo[-1][:3])
1840
sys.stderr.write(' see ~/.bzr.log for debug information\n')
1844
1954
def main(argv):
1846
bzrlib.trace.open_tracefile(argv)
1956
bzrlib.trace.log_startup(argv)
1957
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1851
return run_bzr(argv[1:])
1853
# do this here inside the exception wrappers to catch EPIPE
1856
quiet = isinstance(e, (BzrCommandError))
1857
_report_exception('error: ' + str(e), quiet=quiet)
1860
# some explanation or hints
1863
except AssertionError, e:
1864
msg = 'assertion failed'
1866
msg += ': ' + str(e)
1867
_report_exception(msg)
1869
except KeyboardInterrupt, e:
1870
_report_exception('interrupted', quiet=True)
1872
except Exception, e:
1875
if (isinstance(e, IOError)
1876
and hasattr(e, 'errno')
1877
and e.errno == errno.EPIPE):
1881
msg = str(e).rstrip('\n')
1882
_report_exception(msg, quiet)
1885
bzrlib.trace.close_trace()
1961
return run_bzr(argv[1:])
1963
# do this here inside the exception wrappers to catch EPIPE
1965
except BzrCommandError, e:
1966
# command line syntax error, etc
1970
bzrlib.trace.log_exception()
1972
except AssertionError, e:
1973
bzrlib.trace.log_exception('assertion failed: ' + str(e))
1975
except KeyboardInterrupt, e:
1976
bzrlib.trace.note('interrupted')
1978
except Exception, e:
1980
if (isinstance(e, IOError)
1981
and hasattr(e, 'errno')
1982
and e.errno == errno.EPIPE):
1983
bzrlib.trace.note('broken pipe')
1986
bzrlib.trace.log_exception()
1888
1990
if __name__ == '__main__':