22
22
import bzrlib.trace
23
23
from bzrlib.trace import mutter, note, log_error, warning
24
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
from bzrlib.branch import Branch
25
from bzrlib.branch import find_branch
26
26
from bzrlib import BZRDIR
27
27
from bzrlib.commands import Command
63
63
files or directories is reported. If a directory is given, status
64
64
is reported for everything inside that directory.
66
If a revision argument is given, the status is calculated against
67
that revision, or between two revisions if two are provided.
66
If a revision is specified, the changes since that revision are shown.
69
# XXX: FIXME: bzr status should accept a -r option to show changes
70
# relative to a revision, or between revisions
72
68
takes_args = ['file*']
73
69
takes_options = ['all', 'show-ids', 'revision']
74
70
aliases = ['st', 'stat']
76
def run(self, all=False, show_ids=False, file_list=None, revision=None):
72
def run(self, all=False, show_ids=False, file_list=None):
78
b = Branch.open_containing(file_list[0])
74
b = find_branch(file_list[0])
79
75
file_list = [b.relpath(x) for x in file_list]
80
76
# special case: only one path was given and it's the root
82
78
if file_list == ['']:
85
b = Branch.open_containing('.')
87
83
from bzrlib.status import show_status
88
84
show_status(b, show_unchanged=all, show_ids=show_ids,
89
specific_files=file_list, revision=revision)
85
specific_files=file_list)
92
88
class cmd_cat_revision(Command):
93
"""Write out metadata for a revision.
95
The revision to print can either be specified by a specific
96
revision identifier, or you can use --revision.
89
"""Write out metadata for a revision."""
100
takes_args = ['revision_id?']
101
takes_options = ['revision']
92
takes_args = ['revision_id']
103
def run(self, revision_id=None, revision=None):
104
from bzrlib.revisionspec import RevisionSpec
94
def run(self, revision_id):
96
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
106
if revision_id is not None and revision is not None:
107
raise BzrCommandError('You can only supply one of revision_id or --revision')
108
if revision_id is None and revision is None:
109
raise BzrCommandError('You must supply either --revision or a revision_id')
110
b = Branch.open_containing('.')
111
if revision_id is not None:
112
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
113
elif revision is not None:
116
raise BzrCommandError('You cannot specify a NULL revision.')
117
revno, rev_id = rev.in_history(b)
118
sys.stdout.write(b.get_revision_xml_file(rev_id).read())
121
99
class cmd_revno(Command):
122
100
"""Show current revision number.
124
102
This is equal to the number of revisions on this branch."""
126
print Branch.open_containing('.').revno()
104
print find_branch('.').revno()
129
107
class cmd_revision_info(Command):
133
111
takes_args = ['revision_info*']
134
112
takes_options = ['revision']
135
def run(self, revision=None, revision_info_list=[]):
136
from bzrlib.revisionspec import RevisionSpec
113
def run(self, revision=None, revision_info_list=None):
114
from bzrlib.branch import find_branch
139
117
if revision is not None:
140
118
revs.extend(revision)
141
119
if revision_info_list is not None:
142
for rev in revision_info_list:
143
revs.append(RevisionSpec(rev))
120
revs.extend(revision_info_list)
144
121
if len(revs) == 0:
145
122
raise BzrCommandError('You must supply a revision identifier')
147
b = Branch.open_containing('.')
150
revinfo = rev.in_history(b)
151
if revinfo.revno is None:
152
print ' %s' % revinfo.rev_id
154
print '%4d %s' % (revinfo.revno, revinfo.rev_id)
127
print '%4d %s' % b.get_revision_info(rev)
157
130
class cmd_add(Command):
172
145
Therefore simply saying 'bzr add' will version all files that
173
146
are currently unknown.
175
Adding a file whose parent directory is not versioned will
176
implicitly add the parent, and so on up to the root. This means
177
you should never need to explictly add a directory, they'll just
178
get added when you add a file in the directory.
148
TODO: Perhaps adding a file whose directly is not versioned should
149
recursively add that parent, rather than giving an error?
180
151
takes_args = ['file*']
181
152
takes_options = ['verbose', 'no-recurse']
220
191
takes_options = ['revision', 'show-ids']
222
193
def run(self, revision=None, show_ids=False):
223
b = Branch.open_containing('.')
225
196
inv = b.read_working_inventory()
227
198
if len(revision) > 1:
228
199
raise BzrCommandError('bzr inventory --revision takes'
229
200
' exactly one revision identifier')
230
inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
201
inv = b.get_revision_inventory(b.lookup_revision(revision[0]))
232
203
for path, entry in inv.entries():
340
317
print "Using last location: %s" % stored_loc
341
318
location = stored_loc
342
319
cache_root = tempfile.mkdtemp()
343
from bzrlib.errors import DivergedBranches
344
br_from = Branch.open_containing(location)
345
location = br_from.base
320
from bzrlib.branch import DivergedBranches
321
br_from = find_branch(location)
322
location = pull_loc(br_from)
346
323
old_revno = br_to.revno()
348
from bzrlib.errors import DivergedBranches
349
br_from = Branch.open(location)
350
br_from.setup_caching(cache_root)
351
location = br_from.base
325
from branch import find_cached_branch, DivergedBranches
326
br_from = find_cached_branch(location, cache_root)
327
location = pull_loc(br_from)
352
328
old_revno = br_to.revno()
354
330
br_to.update_revisions(br_from)
373
349
To retrieve the branch as of a particular revision, supply the --revision
374
350
parameter, as in "branch foo/bar -r 5".
376
--basis is to speed up branching from remote branches. When specified, it
377
copies all the file-contents, inventory and revision data from the basis
378
branch before copying anything from the remote branch.
380
352
takes_args = ['from_location', 'to_location?']
381
takes_options = ['revision', 'basis']
353
takes_options = ['revision']
382
354
aliases = ['get', 'clone']
384
def run(self, from_location, to_location=None, revision=None, basis=None):
385
from bzrlib.branch import copy_branch
356
def run(self, from_location, to_location=None, revision=None):
357
from bzrlib.branch import copy_branch, find_cached_branch
388
360
from shutil import rmtree
394
366
raise BzrCommandError(
395
367
'bzr branch --revision takes exactly 1 revision value')
397
br_from = Branch.open(from_location)
369
br_from = find_cached_branch(from_location, cache_root)
398
370
except OSError, e:
399
371
if e.errno == errno.ENOENT:
400
372
raise BzrCommandError('Source location "%s" does not'
401
373
' exist.' % to_location)
404
br_from.setup_caching(cache_root)
405
if basis is not None:
406
basis_branch = Branch.open_containing(basis)
409
if len(revision) == 1 and revision[0] is not None:
410
revision_id = revision[0].in_history(br_from)[1]
413
376
if to_location is None:
414
377
to_location = os.path.basename(from_location.rstrip("/\\"))
427
copy_branch(br_from, to_location, revision_id, basis_branch)
390
copy_branch(br_from, to_location, revision[0])
428
391
except bzrlib.errors.NoSuchRevision:
429
392
rmtree(to_location)
430
393
msg = "The branch %s has no revision %d." % (from_location, revision[0])
431
394
raise BzrCommandError(msg)
432
except bzrlib.errors.UnlistableBranch:
433
msg = "The branch %s cannot be used as a --basis"
435
396
rmtree(cache_root)
719
680
direction = (forward and 'forward') or 'reverse'
722
b = Branch.open_containing(filename)
683
b = find_branch(filename)
723
684
fp = b.relpath(filename)
725
686
file_id = b.read_working_inventory().path2id(fp)
727
688
file_id = None # points to branch root
729
b = Branch.open_containing('.')
732
693
if revision is None:
735
696
elif len(revision) == 1:
736
rev1 = rev2 = revision[0].in_history(b).revno
697
rev1 = rev2 = b.get_revision_info(revision[0])[0]
737
698
elif len(revision) == 2:
738
rev1 = revision[0].in_history(b).revno
739
rev2 = revision[1].in_history(b).revno
699
rev1 = b.get_revision_info(revision[0])[0]
700
rev2 = b.get_revision_info(revision[1])[0]
741
702
raise BzrCommandError('bzr log --revision takes one or two values.')
928
889
takes_options = ['revision', 'format', 'root']
929
890
def run(self, dest, revision=None, format=None, root=None):
931
b = Branch.open_containing('.')
932
893
if revision is None:
933
894
rev_id = b.last_revision()
935
896
if len(revision) != 1:
936
897
raise BzrError('bzr export --revision takes exactly 1 argument')
937
rev_id = revision[0].in_history(b).rev_id
898
revno, rev_id = b.get_revision_info(revision[0])
938
899
t = b.revision_tree(rev_id)
939
900
root, ext = os.path.splitext(dest)
956
917
takes_args = ['filename']
958
919
def run(self, filename, revision=None):
960
921
raise BzrCommandError("bzr cat requires a revision number")
961
922
elif len(revision) != 1:
962
923
raise BzrCommandError("bzr cat --revision takes exactly one number")
963
b = Branch.open_containing('.')
964
b.print_file(b.relpath(filename), revision[0].in_history(b).revno)
925
b.print_file(b.relpath(filename), revision[0])
967
928
class cmd_local_time_offset(Command):
1163
1128
def run(self, branch, other):
1164
1129
from bzrlib.revision import common_ancestor, MultipleRevisionSources
1166
branch1 = Branch.open_containing(branch)
1167
branch2 = Branch.open_containing(other)
1131
branch1 = find_branch(branch)
1132
branch2 = find_branch(other)
1169
1134
history_1 = branch1.revision_history()
1170
1135
history_2 = branch2.revision_history()
1233
1198
other = [branch, -1]
1235
1200
if len(revision) == 1:
1201
other = [branch, revision[0]]
1236
1202
base = [None, None]
1237
other = [branch, revision[0].in_history(branch).revno]
1239
1204
assert len(revision) == 2
1240
1205
if None in revision:
1241
1206
raise BzrCommandError(
1242
1207
"Merge doesn't permit that revision specifier.")
1243
from bzrlib.branch import Branch
1244
b = Branch.open(branch)
1246
base = [branch, revision[0].in_history(b).revno]
1247
other = [branch, revision[1].in_history(b).revno]
1208
base = [branch, revision[0]]
1209
other = [branch, revision[1]]
1250
1212
merge(other, base, check_clean=(not force), merge_type=merge_type)
1278
1240
if len(file_list) == 0:
1279
1241
raise BzrCommandError("No files specified")
1280
1242
if revision is None:
1282
1244
elif len(revision) != 1:
1283
1245
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1285
b = Branch.open_containing('.')
1286
revno = revision[0].in_history(b).revno
1287
merge(('.', revno), parse_spec('.'),
1246
merge(('.', revision[0]), parse_spec('.'),
1288
1247
check_clean=False,
1289
1248
ignore_zero=True,
1290
1249
backup_files=not no_backup,
1291
1250
file_list=file_list)
1292
1251
if not file_list:
1293
Branch.open_containing('.').set_pending_merges([])
1252
Branch('.').set_pending_merges([])
1296
1255
class cmd_assert_fail(Command):
1372
1331
print "Using last location: %s" % parent
1373
1332
remote = parent
1374
1333
elif parent is None:
1375
# We only update parent if it did not exist, missing
1376
# should not change the parent
1377
b.set_parent(remote)
1378
br_remote = Branch.open_containing(remote)
1334
# We only update x-pull if it did not exist, missing should not change the parent
1335
b.controlfile('x-pull', 'wb').write(remote + '\n')
1336
br_remote = find_branch(remote)
1380
1338
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)