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
54
54
def _parse_revision_str(revstr):
55
55
"""This handles a revision string -> revno.
57
It supports integers directly, but everything else it
58
defers for passing to Branch.get_revision_info()
60
>>> _parse_revision_str('234')
62
>>> _parse_revision_str('234..567')
64
>>> _parse_revision_str('..')
66
>>> _parse_revision_str('..234')
68
>>> _parse_revision_str('234..')
70
>>> _parse_revision_str('234..456..789') # Maybe this should be an error
72
>>> _parse_revision_str('234....789') # Error?
74
>>> _parse_revision_str('revid:test@other.com-234234')
75
['revid:test@other.com-234234']
76
>>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
77
['revid:test@other.com-234234', 'revid:test@other.com-234235']
78
>>> _parse_revision_str('revid:test@other.com-234234..23')
79
['revid:test@other.com-234234', 23]
80
>>> _parse_revision_str('date:2005-04-12')
82
>>> _parse_revision_str('date:2005-04-12 12:24:33')
83
['date:2005-04-12 12:24:33']
84
>>> _parse_revision_str('date:2005-04-12T12:24:33')
85
['date:2005-04-12T12:24:33']
86
>>> _parse_revision_str('date:2005-04-12,12:24:33')
87
['date:2005-04-12,12:24:33']
88
>>> _parse_revision_str('-5..23')
90
>>> _parse_revision_str('-5')
92
>>> _parse_revision_str('123a')
94
>>> _parse_revision_str('abc')
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' -> ?
98
old_format_re = re.compile('\d*:\d*')
99
m = old_format_re.match(revstr)
101
warning('Colon separator for revision numbers is deprecated.'
104
for rev in revstr.split(':'):
106
revs.append(int(rev))
111
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])
368
335
print find_branch('.').revno()
370
class cmd_revision_info(Command):
371
"""Show revision number and revision id for a given revision identifier.
374
takes_args = ['revision_info*']
375
takes_options = ['revision']
376
def run(self, revision=None, revision_info_list=None):
377
from bzrlib.branch import find_branch
380
if revision is not None:
381
revs.extend(revision)
382
if revision_info_list is not None:
383
revs.extend(revision_info_list)
385
raise BzrCommandError('You must supply a revision identifier')
390
print '%4d %s' % b.get_revision_info(rev)
393
338
class cmd_add(Command):
394
339
"""Add specified files or directories.
456
401
if revision == None:
457
402
inv = b.read_working_inventory()
459
if len(revision) > 1:
460
raise BzrCommandError('bzr inventory --revision takes'
461
' exactly one revision identifier')
462
inv = b.get_revision_inventory(b.lookup_revision(revision[0]))
404
inv = b.get_revision_inventory(b.lookup_revision(revision))
464
406
for path, entry in inv.entries():
618
556
br_to = Branch(to_location, init=True)
620
br_to.set_root_id(br_from.get_root_id())
623
revno = br_to.lookup_revision(revision[0])
625
br_to.update_revisions(br_from, stop_revision=revno)
626
except NoSuchRevision:
628
msg = "The branch %s has no revision %d." % (from_location,
630
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)
632
565
merge((to_location, -1), (to_location, 0), this_dir=to_location,
633
566
check_clean=False, ignore_zero=True)
634
567
from_location = pull_loc(br_from)
804
737
b = find_branch('.')
806
# TODO: Make show_diff support taking 2 arguments
808
if revision is not None:
809
if len(revision) != 1:
810
raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
811
base_rev = revision[0]
813
show_diff(b, base_rev, specific_files=file_list,
739
show_diff(b, revision, specific_files=file_list,
814
740
external_diff_options=diff_options)
844
770
"""List files modified in working tree."""
847
from bzrlib.diff import compare_trees
849
774
b = find_branch('.')
850
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.
852
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)
891
830
-r revision requests a specific revision, -r :end or -r begin: are
894
--message allows you to give a regular expression, which will be evaluated
895
so that only matching entries will be displayed.
897
833
TODO: Make --revision support uuid: and hash: [future tag:] notation.
901
837
takes_args = ['filename?']
902
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
838
takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long']
904
840
def run(self, filename=None, timezone='original',
911
846
from bzrlib.branch import find_branch
912
847
from bzrlib.log import log_formatter, show_log
925
860
b = find_branch('.')
931
elif len(revision) == 1:
932
rev1 = rev2 = b.get_revision_info(revision[0])[0]
933
elif len(revision) == 2:
934
rev1 = b.get_revision_info(revision[0])[0]
935
rev2 = b.get_revision_info(revision[1])[0]
864
revision = [None, None]
865
elif isinstance(revision, int):
866
revision = [revision, revision]
937
raise BzrCommandError('bzr log --revision takes one or two values.')
871
assert len(revision) == 2
944
873
mutter('encoding log as %r' % bzrlib.user_encoding)
1114
1042
If no revision is specified this exports the last committed revision.
1116
1044
Format may be an "exporter" name, such as tar, tgz, tbz2. If none is
1117
given, try to find the format with the extension. If no extension
1118
is found exports to a directory (equivalent to --format=dir).
1120
Root may be the top directory for tar, tgz and tbz2 formats. If none
1121
is given, the top directory will be the root name of the file."""
1045
given, exports to a directory (equivalent to --format=dir)."""
1122
1046
# TODO: list known exporters
1123
1047
takes_args = ['dest']
1124
takes_options = ['revision', 'format', 'root']
1125
def run(self, dest, revision=None, format=None, root=None):
1048
takes_options = ['revision', 'format']
1049
def run(self, dest, revision=None, format='dir'):
1127
1050
b = find_branch('.')
1128
if revision is None:
1129
rev_id = b.last_patch()
1051
if revision == None:
1052
rh = b.revision_history()[-1]
1131
if len(revision) != 1:
1132
raise BzrError('bzr export --revision takes exactly 1 argument')
1133
revno, rev_id = b.get_revision_info(revision[0])
1134
t = b.revision_tree(rev_id)
1135
root, ext = os.path.splitext(dest)
1137
if ext in (".tar",):
1139
elif ext in (".gz", ".tgz"):
1141
elif ext in (".bz2", ".tbz2"):
1145
t.export(dest, format, root)
1054
rh = b.lookup_revision(int(revision))
1055
t = b.revision_tree(rh)
1056
t.export(dest, format)
1148
1059
class cmd_cat(Command):
1154
1065
def run(self, filename, revision=None):
1155
1066
if revision == None:
1156
1067
raise BzrCommandError("bzr cat requires a revision number")
1157
elif len(revision) != 1:
1158
raise BzrCommandError("bzr cat --revision takes exactly one number")
1159
1068
b = find_branch('.')
1160
b.print_file(b.relpath(filename), revision[0])
1069
b.print_file(b.relpath(filename), int(revision))
1163
1072
class cmd_local_time_offset(Command):
1184
1093
TODO: Strict commit that fails if there are unknown or deleted files.
1186
1095
takes_args = ['selected*']
1187
takes_options = ['message', 'file', 'verbose', 'unchanged']
1096
takes_options = ['message', 'file', 'verbose']
1188
1097
aliases = ['ci', 'checkin']
1190
def run(self, message=None, file=None, verbose=True, selected_list=None,
1192
from bzrlib.errors import PointlessCommit
1099
def run(self, message=None, file=None, verbose=True, selected_list=None):
1100
from bzrlib.commit import commit
1193
1101
from bzrlib.osutils import get_text_message
1195
1103
## Warning: shadows builtin file()
1214
1122
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1216
1124
b = find_branch('.')
1219
b.commit(message, verbose=verbose,
1220
specific_files=selected_list,
1221
allow_pointless=unchanged)
1222
except PointlessCommit:
1223
# FIXME: This should really happen before the file is read in;
1224
# perhaps prepare the commit; get the message; then actually commit
1225
raise BzrCommandError("no changes to commit",
1226
["use --unchanged to commit anyhow"])
1125
commit(b, message, verbose=verbose, specific_files=selected_list)
1229
1128
class cmd_check(Command):
1392
1285
takes_options = ['revision']
1394
def run(self, revision=None):
1287
def run(self, revision=-1):
1395
1288
from bzrlib.merge import merge
1396
if revision is None:
1398
elif len(revision) != 1:
1399
raise BzrCommandError('bzr merge-revert --revision takes exactly 1 argument')
1400
merge(('.', revision[0]), parse_spec('.'),
1289
merge(('.', revision), parse_spec('.'),
1401
1290
check_clean=False,
1402
1291
ignore_zero=True)
1430
1329
import bzrlib.plugin
1431
from inspect import getdoc
1432
1330
from pprint import pprint
1433
for plugin in bzrlib.plugin.all_plugins:
1434
print plugin.__path__[0]
1437
print '\t', d.split('\n')[0]
1439
#pprint(bzrlib.plugin.all_plugins)
1331
pprint(bzrlib.plugin.all_plugins)
1493
1383
>>> parse_args('commit --message=biter'.split())
1494
1384
(['commit'], {'message': u'biter'})
1495
1385
>>> parse_args('log -r 500'.split())
1496
(['log'], {'revision': [500]})
1497
>>> parse_args('log -r500..600'.split())
1386
(['log'], {'revision': 500})
1387
>>> parse_args('log -r500:600'.split())
1498
1388
(['log'], {'revision': [500, 600]})
1499
>>> parse_args('log -vr500..600'.split())
1389
>>> parse_args('log -vr500:600'.split())
1500
1390
(['log'], {'verbose': True, 'revision': [500, 600]})
1501
>>> parse_args('log -rv500..600'.split()) #the r takes an argument
1502
(['log'], {'revision': ['v500', 600]})
1391
>>> parse_args('log -rv500:600'.split()) #the r takes an argument
1392
Traceback (most recent call last):
1394
ValueError: invalid literal for int(): v500