22
22
import bzrlib.trace
23
23
from bzrlib.trace import mutter, note, log_error, warning
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
25
from bzrlib.branch import find_branch
24
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
from bzrlib.branch import Branch
26
26
from bzrlib import BZRDIR
27
27
from bzrlib.commands import Command
62
62
directory is shown. Otherwise, only the status of the specified
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
69
# XXX: FIXME: bzr status should accept a -r option to show changes
67
70
# relative to a revision, or between revisions
70
73
takes_options = ['all', 'show-ids']
71
74
aliases = ['st', 'stat']
73
def run(self, all=False, show_ids=False, file_list=None):
76
def run(self, all=False, show_ids=False, file_list=None, revision=None):
75
b = find_branch(file_list[0])
78
b = Branch.open_containing(file_list[0])
76
79
file_list = [b.relpath(x) for x in file_list]
77
80
# special case: only one path was given and it's the root
79
82
if file_list == ['']:
85
b = Branch.open_containing('.')
84
87
from bzrlib.status import show_status
85
88
show_status(b, show_unchanged=all, show_ids=show_ids,
86
specific_files=file_list)
89
specific_files=file_list, revision=revision)
89
92
class cmd_cat_revision(Command):
90
"""Write out metadata for a revision."""
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.
93
takes_args = ['revision_id']
100
takes_args = ['revision_id?']
101
takes_options = ['revision']
95
def run(self, revision_id):
97
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
103
def run(self, revision_id=None, revision=None):
104
from bzrlib.revisionspec import RevisionSpec
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())
100
121
class cmd_revno(Command):
101
122
"""Show current revision number.
103
124
This is equal to the number of revisions on this branch."""
105
print find_branch('.').revno()
126
print Branch.open_containing('.').revno()
108
129
class cmd_revision_info(Command):
112
133
takes_args = ['revision_info*']
113
134
takes_options = ['revision']
114
def run(self, revision=None, revision_info_list=None):
115
from bzrlib.branch import find_branch
135
def run(self, revision=None, revision_info_list=[]):
136
from bzrlib.revisionspec import RevisionSpec
118
139
if revision is not None:
119
140
revs.extend(revision)
120
141
if revision_info_list is not None:
121
revs.extend(revision_info_list)
142
for rev in revision_info_list:
143
revs.append(RevisionSpec(rev))
122
144
if len(revs) == 0:
123
145
raise BzrCommandError('You must supply a revision identifier')
147
b = Branch.open_containing('.')
128
print '%4d %s' % b.get_revision_info(rev)
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)
131
157
class cmd_add(Command):
194
220
takes_options = ['revision', 'show-ids']
196
222
def run(self, revision=None, show_ids=False):
223
b = Branch.open_containing('.')
199
225
inv = b.read_working_inventory()
201
227
if len(revision) > 1:
202
228
raise BzrCommandError('bzr inventory --revision takes'
203
229
' exactly one revision identifier')
204
inv = b.get_revision_inventory(b.lookup_revision(revision[0]))
230
inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
206
232
for path, entry in inv.entries():
221
247
takes_args = ['source$', 'dest']
222
248
def run(self, source_list, dest):
249
b = Branch.open_containing('.')
225
251
# TODO: glob expansion on windows?
226
252
b.move([b.relpath(s) for s in source_list], b.relpath(dest))
314
340
print "Using last location: %s" % stored_loc
315
341
location = stored_loc
316
342
cache_root = tempfile.mkdtemp()
317
from bzrlib.branch import DivergedBranches
318
br_from = find_branch(location)
343
from bzrlib.errors import DivergedBranches
344
br_from = Branch.open_containing(location)
319
345
location = br_from.base
320
346
old_revno = br_to.revno()
322
from branch import find_cached_branch, DivergedBranches
323
br_from = find_cached_branch(location, cache_root)
348
from bzrlib.errors import DivergedBranches
349
br_from = Branch.open(location)
350
br_from.setup_caching(cache_root)
324
351
location = br_from.base
325
352
old_revno = br_to.revno()
346
373
To retrieve the branch as of a particular revision, supply the --revision
347
374
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.
349
380
takes_args = ['from_location', 'to_location?']
350
takes_options = ['revision']
381
takes_options = ['revision', 'basis']
351
382
aliases = ['get', 'clone']
353
def run(self, from_location, to_location=None, revision=None):
354
from bzrlib.branch import copy_branch, find_cached_branch
384
def run(self, from_location, to_location=None, revision=None, basis=None):
385
from bzrlib.clone import copy_branch
357
388
from shutil import rmtree
363
394
raise BzrCommandError(
364
395
'bzr branch --revision takes exactly 1 revision value')
366
br_from = find_cached_branch(from_location, cache_root)
397
br_from = Branch.open(from_location)
367
398
except OSError, e:
368
399
if e.errno == errno.ENOENT:
369
400
raise BzrCommandError('Source location "%s" does not'
370
401
' 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]
373
413
if to_location is None:
374
414
to_location = os.path.basename(from_location.rstrip("/\\"))
387
copy_branch(br_from, to_location, revision[0])
427
copy_branch(br_from, to_location, revision_id, basis_branch)
388
428
except bzrlib.errors.NoSuchRevision:
389
429
rmtree(to_location)
390
430
msg = "The branch %s has no revision %d." % (from_location, revision[0])
391
431
raise BzrCommandError(msg)
432
except bzrlib.errors.UnlistableBranch:
433
msg = "The branch %s cannot be used as a --basis"
393
435
rmtree(cache_root)
477
519
"""Display list of revision ids on this branch."""
480
for patchid in find_branch('.').revision_history():
522
for patchid in Branch.open_containing('.').revision_history():
526
class cmd_ancestry(Command):
527
"""List all revisions merged into this branch."""
531
for revision_id in b.get_ancestry(b.last_revision()):
484
535
class cmd_directories(Command):
485
536
"""Display list of versioned directories in this branch."""
487
for name, ie in find_branch('.').read_working_inventory().directories():
538
for name, ie in Branch.open_containing('.').read_working_inventory().directories():
668
718
direction = (forward and 'forward') or 'reverse'
671
b = find_branch(filename)
721
b = Branch.open_containing(filename)
672
722
fp = b.relpath(filename)
674
724
file_id = b.read_working_inventory().path2id(fp)
676
726
file_id = None # points to branch root
728
b = Branch.open_containing('.')
681
731
if revision is None:
684
734
elif len(revision) == 1:
685
rev1 = rev2 = b.get_revision_info(revision[0])[0]
735
rev1 = rev2 = revision[0].in_history(b).revno
686
736
elif len(revision) == 2:
687
rev1 = b.get_revision_info(revision[0])[0]
688
rev2 = b.get_revision_info(revision[1])[0]
737
rev1 = revision[0].in_history(b).revno
738
rev2 = revision[1].in_history(b).revno
690
740
raise BzrCommandError('bzr log --revision takes one or two values.')
728
778
takes_args = ["filename"]
729
779
def run(self, filename):
730
b = find_branch(filename)
780
b = Branch.open_containing(filename)
731
781
inv = b.read_working_inventory()
732
782
file_id = inv.path2id(b.relpath(filename))
733
783
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
743
793
def run(self, revision=None, verbose=False):
794
b = Branch.open_containing('.')
745
795
if revision == None:
746
796
tree = b.working_tree()
748
tree = b.revision_tree(b.lookup_revision(revision))
798
tree = b.revision_tree(revision.in_history(b).rev_id)
750
800
for fp, fc, kind, fid in tree.list_files():
877
927
takes_options = ['revision', 'format', 'root']
878
928
def run(self, dest, revision=None, format=None, root=None):
930
b = Branch.open_containing('.')
881
931
if revision is None:
882
rev_id = b.last_patch()
932
rev_id = b.last_revision()
884
934
if len(revision) != 1:
885
935
raise BzrError('bzr export --revision takes exactly 1 argument')
886
revno, rev_id = b.get_revision_info(revision[0])
936
rev_id = revision[0].in_history(b).rev_id
887
937
t = b.revision_tree(rev_id)
888
root, ext = os.path.splitext(dest)
938
arg_root, ext = os.path.splitext(os.path.basename(dest))
939
if ext in ('.gz', '.bz2'):
940
new_root, new_ext = os.path.splitext(arg_root)
941
if new_ext == '.tar':
890
947
if ext in (".tar",):
892
elif ext in (".gz", ".tgz"):
949
elif ext in (".tar.gz", ".tgz"):
894
elif ext in (".bz2", ".tbz2"):
951
elif ext in (".tar.bz2", ".tbz2"):
905
962
takes_args = ['filename']
907
964
def run(self, filename, revision=None):
909
966
raise BzrCommandError("bzr cat requires a revision number")
910
967
elif len(revision) != 1:
911
968
raise BzrCommandError("bzr cat --revision takes exactly one number")
913
b.print_file(b.relpath(filename), revision[0])
969
b = Branch.open_containing('.')
970
b.print_file(b.relpath(filename), revision[0].in_history(b).revno)
916
973
class cmd_local_time_offset(Command):
943
1000
aliases = ['ci', 'checkin']
945
1002
# TODO: Give better message for -s, --summary, used by tla people
1004
# XXX: verbose currently does nothing
947
1006
def run(self, message=None, file=None, verbose=True, selected_list=None,
948
1007
unchanged=False):
1108
1169
def run(self, branch, other):
1109
1170
from bzrlib.revision import common_ancestor, MultipleRevisionSources
1111
branch1 = find_branch(branch)
1112
branch2 = find_branch(other)
1172
branch1 = Branch.open_containing(branch)
1173
branch2 = Branch.open_containing(other)
1114
1175
history_1 = branch1.revision_history()
1115
1176
history_2 = branch2.revision_history()
1117
last1 = branch1.last_patch()
1118
last2 = branch2.last_patch()
1178
last1 = branch1.last_revision()
1179
last2 = branch2.last_revision()
1120
1181
source = MultipleRevisionSources(branch1, branch2)
1178
1239
other = [branch, -1]
1180
1241
if len(revision) == 1:
1181
other = [branch, revision[0]]
1182
1242
base = [None, None]
1243
other = [branch, revision[0].in_history(branch).revno]
1184
1245
assert len(revision) == 2
1185
1246
if None in revision:
1186
1247
raise BzrCommandError(
1187
1248
"Merge doesn't permit that revision specifier.")
1188
base = [branch, revision[0]]
1189
other = [branch, revision[1]]
1249
b = Branch.open(branch)
1251
base = [branch, revision[0].in_history(b).revno]
1252
other = [branch, revision[1].in_history(b).revno]
1192
1255
merge(other, base, check_clean=(not force), merge_type=merge_type)
1214
1277
def run(self, revision=None, no_backup=False, file_list=None):
1215
1278
from bzrlib.merge import merge
1216
from bzrlib.branch import Branch
1217
1279
from bzrlib.commands import parse_spec
1219
1281
if file_list is not None:
1220
1282
if len(file_list) == 0:
1221
1283
raise BzrCommandError("No files specified")
1222
1284
if revision is None:
1224
1286
elif len(revision) != 1:
1225
1287
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1226
merge(('.', revision[0]), parse_spec('.'),
1289
b = Branch.open_containing('.')
1290
revno = revision[0].in_history(b).revno
1291
merge(('.', revno), parse_spec('.'),
1227
1292
check_clean=False,
1228
1293
ignore_zero=True,
1229
1294
backup_files=not no_backup,
1230
1295
file_list=file_list)
1231
1296
if not file_list:
1232
Branch('.').set_pending_merges([])
1297
Branch.open_containing('.').set_pending_merges([])
1235
1300
class cmd_assert_fail(Command):
1267
1332
shellcomplete.shellcomplete(context)
1335
class cmd_fetch(Command):
1336
"""Copy in history from another branch but don't merge it.
1338
This is an internal method used for pull and merge."""
1340
takes_args = ['from_branch', 'to_branch']
1341
def run(self, from_branch, to_branch):
1342
from bzrlib.fetch import Fetcher
1343
from bzrlib.branch import Branch
1344
from_b = Branch(from_branch)
1345
to_b = Branch(to_branch)
1346
Fetcher(to_b, from_b)
1270
1350
class cmd_missing(Command):
1271
1351
"""What is missing in this branch relative to other branch.
1353
# TODO: rewrite this in terms of ancestry so that it shows only
1273
1356
takes_args = ['remote?']
1274
1357
aliases = ['mis', 'miss']
1275
1358
# We don't have to add quiet to the list, because
1293
1376
print "Using last location: %s" % parent
1294
1377
remote = parent
1295
1378
elif parent is None:
1296
# We only update parent if it did not exist, missing should not change the parent
1379
# We only update parent if it did not exist, missing
1380
# should not change the parent
1297
1381
b.set_parent(remote)
1298
br_remote = find_branch(remote)
1382
br_remote = Branch.open_containing(remote)
1300
1383
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1304
1386
class cmd_plugins(Command):
1305
1387
"""List plugins"""