22
from bzrlib.trace import mutter, note, log_error, warning
22
from bzrlib.trace import mutter, note, log_error
23
23
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
24
24
from bzrlib.branch import find_branch
25
25
from bzrlib import BZRDIR
51
51
assert cmd.startswith("cmd_")
52
52
return cmd[4:].replace('_','-')
55
54
def _parse_revision_str(revstr):
56
"""This handles a revision string -> revno.
58
This always returns a list. The list will have one element for
60
It supports integers directly, but everything else it
61
defers for passing to Branch.get_revision_info()
63
>>> _parse_revision_str('234')
65
>>> _parse_revision_str('234..567')
67
>>> _parse_revision_str('..')
69
>>> _parse_revision_str('..234')
71
>>> _parse_revision_str('234..')
73
>>> _parse_revision_str('234..456..789') # Maybe this should be an error
75
>>> _parse_revision_str('234....789') # Error?
77
>>> _parse_revision_str('revid:test@other.com-234234')
78
['revid:test@other.com-234234']
79
>>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
80
['revid:test@other.com-234234', 'revid:test@other.com-234235']
81
>>> _parse_revision_str('revid:test@other.com-234234..23')
82
['revid:test@other.com-234234', 23]
83
>>> _parse_revision_str('date:2005-04-12')
85
>>> _parse_revision_str('date:2005-04-12 12:24:33')
86
['date:2005-04-12 12:24:33']
87
>>> _parse_revision_str('date:2005-04-12T12:24:33')
88
['date:2005-04-12T12:24:33']
89
>>> _parse_revision_str('date:2005-04-12,12:24:33')
90
['date:2005-04-12,12:24:33']
91
>>> _parse_revision_str('-5..23')
93
>>> _parse_revision_str('-5')
95
>>> _parse_revision_str('123a')
97
>>> _parse_revision_str('abc')
55
"""This handles a revision string -> revno.
57
There are several possibilities:
60
'234:345' -> [234, 345]
64
In the future we will also support:
65
'uuid:blah-blah-blah' -> ?
66
'hash:blahblahblah' -> ?
101
old_format_re = re.compile('\d*:\d*')
102
m = old_format_re.match(revstr)
104
warning('Colon separator for revision numbers is deprecated.'
107
for rev in revstr.split(':'):
109
revs.append(int(rev))
114
for x in revstr.split('..'):
70
if revstr.find(':') != -1:
71
revs = revstr.split(':')
73
raise ValueError('More than 2 pieces not supported for --revision: %r' % revstr)
78
revs[0] = int(revs[0])
83
revs[1] = int(revs[1])
332
296
directory is shown. Otherwise, only the status of the specified
333
297
files or directories is reported. If a directory is given, status
334
298
is reported for everything inside that directory.
336
If a revision is specified, the changes since that revision are shown.
338
300
takes_args = ['file*']
339
takes_options = ['all', 'show-ids', 'revision']
301
takes_options = ['all', 'show-ids']
340
302
aliases = ['st', 'stat']
342
304
def run(self, all=False, show_ids=False, file_list=None):
351
313
b = find_branch('.')
353
from bzrlib.status import show_status
354
show_status(b, show_unchanged=all, show_ids=show_ids,
355
specific_files=file_list)
315
status.show_status(b, show_unchanged=all, show_ids=show_ids,
316
specific_files=file_list)
358
319
class cmd_cat_revision(Command):
374
335
print find_branch('.').revno()
376
class cmd_revision_info(Command):
377
"""Show revision number and revision id for a given revision identifier.
380
takes_args = ['revision_info*']
381
takes_options = ['revision']
382
def run(self, revision=None, revision_info_list=None):
383
from bzrlib.branch import find_branch
386
if revision is not None:
387
revs.extend(revision)
388
if revision_info_list is not None:
389
revs.extend(revision_info_list)
391
raise BzrCommandError('You must supply a revision identifier')
396
print '%4d %s' % b.get_revision_info(rev)
399
338
class cmd_add(Command):
400
339
"""Add specified files or directories.
462
401
if revision == None:
463
402
inv = b.read_working_inventory()
465
if len(revision) > 1:
466
raise BzrCommandError('bzr inventory --revision takes'
467
' exactly one revision identifier')
468
inv = b.get_revision_inventory(b.lookup_revision(revision[0]))
404
inv = b.get_revision_inventory(b.lookup_revision(revision))
470
406
for path, entry in inv.entries():
626
556
br_to = Branch(to_location, init=True)
628
br_to.set_root_id(br_from.get_root_id())
631
if revision[0] is None:
632
revno = br_from.revno()
634
revno, rev_id = br_from.get_revision_info(revision[0])
636
br_to.update_revisions(br_from, stop_revision=revno)
637
except NoSuchRevision:
639
msg = "The branch %s has no revision %d." % (from_location,
641
raise BzrCommandError(msg)
559
br_to.update_revisions(br_from, stop_revision=revision)
560
except NoSuchRevision:
562
msg = "The branch %s has no revision %d." % (from_location,
564
raise BzrCommandError(msg)
643
565
merge((to_location, -1), (to_location, 0), this_dir=to_location,
644
566
check_clean=False, ignore_zero=True)
645
567
from_location = pull_loc(br_from)
815
737
b = find_branch('.')
817
# TODO: Make show_diff support taking 2 arguments
819
if revision is not None:
820
if len(revision) != 1:
821
raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
822
base_rev = revision[0]
824
show_diff(b, base_rev, specific_files=file_list,
739
show_diff(b, revision, specific_files=file_list,
825
740
external_diff_options=diff_options)
855
770
"""List files modified in working tree."""
858
from bzrlib.diff import compare_trees
860
774
b = find_branch('.')
861
td = compare_trees(b.basis_tree(), b.working_tree())
775
inv = b.read_working_inventory()
776
sc = statcache.update_cache(b, inv)
777
basis = b.basis_tree()
778
basis_inv = basis.inventory
780
# We used to do this through iter_entries(), but that's slow
781
# when most of the files are unmodified, as is usually the
782
# case. So instead we iterate by inventory entry, and only
783
# calculate paths as necessary.
863
for path, id, kind in td.modified:
785
for file_id in basis_inv:
786
cacheentry = sc.get(file_id)
787
if not cacheentry: # deleted
789
ie = basis_inv[file_id]
790
if cacheentry[statcache.SC_SHA1] != ie.text_sha1:
791
path = inv.id2path(file_id)
902
830
-r revision requests a specific revision, -r :end or -r begin: are
905
--message allows you to give a regular expression, which will be evaluated
906
so that only matching entries will be displayed.
908
833
TODO: Make --revision support uuid: and hash: [future tag:] notation.
912
837
takes_args = ['filename?']
913
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
838
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision']
915
840
def run(self, filename=None, timezone='original',
922
845
from bzrlib.branch import find_branch
923
846
from bzrlib.log import log_formatter, show_log
936
859
b = find_branch('.')
942
elif len(revision) == 1:
943
rev1 = rev2 = b.get_revision_info(revision[0])[0]
944
elif len(revision) == 2:
945
rev1 = b.get_revision_info(revision[0])[0]
946
rev2 = b.get_revision_info(revision[1])[0]
863
revision = [None, None]
864
elif isinstance(revision, int):
865
revision = [revision, revision]
948
raise BzrCommandError('bzr log --revision takes one or two values.')
870
assert len(revision) == 2
955
872
mutter('encoding log as %r' % bzrlib.user_encoding)
1125
1037
If no revision is specified this exports the last committed revision.
1127
1039
Format may be an "exporter" name, such as tar, tgz, tbz2. If none is
1128
given, try to find the format with the extension. If no extension
1129
is found exports to a directory (equivalent to --format=dir).
1131
Root may be the top directory for tar, tgz and tbz2 formats. If none
1132
is given, the top directory will be the root name of the file."""
1040
given, exports to a directory (equivalent to --format=dir)."""
1133
1041
# TODO: list known exporters
1134
1042
takes_args = ['dest']
1135
takes_options = ['revision', 'format', 'root']
1136
def run(self, dest, revision=None, format=None, root=None):
1043
takes_options = ['revision', 'format']
1044
def run(self, dest, revision=None, format='dir'):
1138
1045
b = find_branch('.')
1139
if revision is None:
1140
rev_id = b.last_patch()
1046
if revision == None:
1047
rh = b.revision_history()[-1]
1142
if len(revision) != 1:
1143
raise BzrError('bzr export --revision takes exactly 1 argument')
1144
revno, rev_id = b.get_revision_info(revision[0])
1145
t = b.revision_tree(rev_id)
1146
root, ext = os.path.splitext(dest)
1148
if ext in (".tar",):
1150
elif ext in (".gz", ".tgz"):
1152
elif ext in (".bz2", ".tbz2"):
1156
t.export(dest, format, root)
1049
rh = b.lookup_revision(int(revision))
1050
t = b.revision_tree(rh)
1051
t.export(dest, format)
1159
1054
class cmd_cat(Command):
1165
1060
def run(self, filename, revision=None):
1166
1061
if revision == None:
1167
1062
raise BzrCommandError("bzr cat requires a revision number")
1168
elif len(revision) != 1:
1169
raise BzrCommandError("bzr cat --revision takes exactly one number")
1170
1063
b = find_branch('.')
1171
b.print_file(b.relpath(filename), revision[0])
1064
b.print_file(b.relpath(filename), int(revision))
1174
1067
class cmd_local_time_offset(Command):
1195
1088
TODO: Strict commit that fails if there are unknown or deleted files.
1197
1090
takes_args = ['selected*']
1198
takes_options = ['message', 'file', 'verbose', 'unchanged']
1091
takes_options = ['message', 'file', 'verbose']
1199
1092
aliases = ['ci', 'checkin']
1201
def run(self, message=None, file=None, verbose=True, selected_list=None,
1203
from bzrlib.errors import PointlessCommit
1094
def run(self, message=None, file=None, verbose=True, selected_list=None):
1095
from bzrlib.commit import commit
1204
1096
from bzrlib.osutils import get_text_message
1206
1098
## Warning: shadows builtin file()
1225
1117
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1227
1119
b = find_branch('.')
1230
b.commit(message, verbose=verbose,
1231
specific_files=selected_list,
1232
allow_pointless=unchanged)
1233
except PointlessCommit:
1234
# FIXME: This should really happen before the file is read in;
1235
# perhaps prepare the commit; get the message; then actually commit
1236
raise BzrCommandError("no changes to commit",
1237
["use --unchanged to commit anyhow"])
1120
commit(b, message, verbose=verbose, specific_files=selected_list)
1240
1123
class cmd_check(Command):
1257
class cmd_scan_cache(Command):
1260
from bzrlib.hashcache import HashCache
1267
print '%6d stats' % c.stat_count
1268
print '%6d in hashcache' % len(c._cache)
1269
print '%6d files removed from cache' % c.removed_count
1270
print '%6d hashes updated' % c.update_count
1271
print '%6d files changed too recently to cache' % c.danger_count
1278
1140
class cmd_upgrade(Command):
1279
1141
"""Upgrade branch storage to current format.
1424
1280
takes_options = ['revision']
1426
def run(self, revision=None):
1282
def run(self, revision=-1):
1427
1283
from bzrlib.merge import merge
1428
if revision is None:
1430
elif len(revision) != 1:
1431
raise BzrCommandError('bzr merge-revert --revision takes exactly 1 argument')
1432
merge(('.', revision[0]), parse_spec('.'),
1284
merge(('.', revision), parse_spec('.'),
1433
1285
check_clean=False,
1434
1286
ignore_zero=True)
1462
1324
import bzrlib.plugin
1463
from inspect import getdoc
1464
1325
from pprint import pprint
1465
for plugin in bzrlib.plugin.all_plugins:
1466
print plugin.__path__[0]
1469
print '\t', d.split('\n')[0]
1471
#pprint(bzrlib.plugin.all_plugins)
1326
pprint(bzrlib.plugin.all_plugins)
1525
1376
>>> parse_args('commit --message=biter'.split())
1526
1377
(['commit'], {'message': u'biter'})
1527
1378
>>> parse_args('log -r 500'.split())
1528
(['log'], {'revision': [500]})
1529
>>> parse_args('log -r500..600'.split())
1379
(['log'], {'revision': 500})
1380
>>> parse_args('log -r500:600'.split())
1530
1381
(['log'], {'revision': [500, 600]})
1531
>>> parse_args('log -vr500..600'.split())
1382
>>> parse_args('log -vr500:600'.split())
1532
1383
(['log'], {'verbose': True, 'revision': [500, 600]})
1533
>>> parse_args('log -rv500..600'.split()) #the r takes an argument
1534
(['log'], {'revision': ['v500', 600]})
1384
>>> parse_args('log -rv500:600'.split()) #the r takes an argument
1385
Traceback (most recent call last):
1387
ValueError: invalid literal for int(): v500