23
from bzrlib.trace import mutter, note, log_error, warning
22
from bzrlib import BZRDIR
23
from bzrlib.commands import Command
24
from bzrlib.branch import Branch
24
25
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
25
26
from bzrlib.errors import DivergedBranches
26
from bzrlib.branch import Branch
27
from bzrlib import BZRDIR
28
from bzrlib.commands import Command
29
27
from bzrlib.option import Option
28
from bzrlib.revisionspec import RevisionSpec
30
from bzrlib.trace import mutter, note, log_error, warning
30
31
from bzrlib.workingtree import WorkingTree
69
70
If a revision argument is given, the status is calculated against
70
71
that revision, or between two revisions if two are provided.
72
74
# XXX: FIXME: bzr status should accept a -r option to show changes
73
75
# relative to a revision, or between revisions
77
# TODO: --no-recurse, --recurse options
75
79
takes_args = ['file*']
76
80
takes_options = ['all', 'show-ids']
77
81
aliases = ['st', 'stat']
79
83
def run(self, all=False, show_ids=False, file_list=None, revision=None):
81
b = Branch.open_containing(file_list[0])
82
tree = WorkingTree(b.base, b)
83
file_list = [tree.relpath(x) for x in file_list]
84
# special case: only one path was given and it's the root
85
b, relpath = Branch.open_containing(file_list[0])
86
if relpath == '' and len(file_list) == 1:
89
# generate relative paths.
90
# note that if this is a remote branch, we would want
91
# relpath against the transport. RBC 20051018
92
tree = WorkingTree(b.base, b)
93
file_list = [tree.relpath(x) for x in file_list]
89
b = Branch.open_containing('.')
95
b = Branch.open_containing('.')[0]
91
97
from bzrlib.status import show_status
92
98
show_status(b, show_unchanged=all, show_ids=show_ids,
105
111
takes_options = ['revision']
107
113
def run(self, revision_id=None, revision=None):
108
from bzrlib.revisionspec import RevisionSpec
110
115
if revision_id is not None and revision is not None:
111
116
raise BzrCommandError('You can only supply one of revision_id or --revision')
112
117
if revision_id is None and revision is None:
113
118
raise BzrCommandError('You must supply either --revision or a revision_id')
114
b = Branch.open_containing('.')
119
b = Branch.open_containing('.')[0]
115
120
if revision_id is not None:
116
121
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
117
122
elif revision is not None:
219
223
def run(self, filename):
220
branch = Branch.open_containing(filename)
221
print WorkingTree(branch.base, branch).relpath(filename)
224
branch, relpath = Branch.open_containing(filename)
224
228
class cmd_inventory(Command):
226
230
takes_options = ['revision', 'show-ids']
228
232
def run(self, revision=None, show_ids=False):
229
b = Branch.open_containing('.')
233
b = Branch.open_containing('.')[0]
230
234
if revision is None:
231
235
inv = b.read_working_inventory()
253
257
takes_args = ['source$', 'dest']
254
258
def run(self, source_list, dest):
255
b = Branch.open_containing('.')
259
b = Branch.open_containing('.')[0]
257
261
# TODO: glob expansion on windows?
258
262
tree = WorkingTree(b.base, b)
276
280
takes_args = ['from_name', 'to_name']
278
282
def run(self, from_name, to_name):
279
b = Branch.open_containing('.')
283
b = Branch.open_containing('.')[0]
280
284
tree = WorkingTree(b.base, b)
281
285
b.rename_one(tree.relpath(from_name), tree.relpath(to_name))
298
302
def run(self, names_list):
299
303
if len(names_list) < 2:
300
304
raise BzrCommandError("missing file argument")
301
b = Branch.open_containing(names_list[0])
305
b = Branch.open_containing(names_list[0])[0]
302
306
tree = WorkingTree(b.base, b)
303
307
rel_names = [tree.relpath(x) for x in names_list]
486
490
def run(self, file_list, verbose=False):
487
b = Branch.open_containing(file_list[0])
491
b = Branch.open_containing(file_list[0])[0]
488
492
tree = WorkingTree(b.base, b)
489
b.remove([tree.relpath(f) for f in file_list], verbose=verbose)
493
tree.remove([tree.relpath(f) for f in file_list], verbose=verbose)
492
496
class cmd_file_id(Command):
500
504
takes_args = ['filename']
501
505
def run(self, filename):
502
b = Branch.open_containing(filename)
503
tree = WorkingTree(b.base, b)
504
i = b.inventory.path2id(tree.relpath(filename))
506
b, relpath = Branch.open_containing(filename)
507
i = b.inventory.path2id(relpath)
506
509
raise BzrError("%r is not a versioned file" % filename)
517
520
takes_args = ['filename']
518
521
def run(self, filename):
519
b = Branch.open_containing(filename)
522
b, relpath = Branch.open_containing(filename)
520
523
inv = b.inventory
521
tree = WorkingTree(b.base, b)
522
fid = inv.path2id(tree.relpath(filename))
524
fid = inv.path2id(relpath)
524
526
raise BzrError("%r is not a versioned file" % filename)
525
527
for fip in inv.get_idpath(fid):
546
548
class cmd_directories(Command):
547
549
"""Display list of versioned directories in this branch."""
549
for name, ie in Branch.open_containing('.').read_working_inventory().directories():
551
for name, ie in Branch.open_containing('.')[0].read_working_inventory().directories():
603
605
from bzrlib.diff import show_diff
606
b = Branch.open_containing(file_list[0])
608
b = Branch.open_containing(file_list[0])[0]
607
609
tree = WorkingTree(b.base, b)
608
610
file_list = [tree.relpath(f) for f in file_list]
609
611
if file_list == ['']:
610
612
# just pointing to top-of-tree
613
b = Branch.open_containing('.')
615
b = Branch.open_containing('.')[0]
615
617
if revision is not None:
616
618
if len(revision) == 1:
639
641
# level of effort but possibly much less IO. (Or possibly not,
640
642
# if the directories are very large...)
641
643
def run(self, show_ids=False):
642
b = Branch.open_containing('.')
644
b = Branch.open_containing('.')[0]
643
645
old = b.basis_tree()
644
646
new = b.working_tree()
645
647
for path, ie in old.inventory.iter_entries():
657
659
from bzrlib.delta import compare_trees
659
b = Branch.open_containing('.')
661
b = Branch.open_containing('.')[0]
660
662
td = compare_trees(b.basis_tree(), b.working_tree())
662
664
for path, id, kind, text_modified, meta_modified in td.modified:
690
692
takes_args = ['filename?']
691
693
def run(self, filename=None):
692
694
"""Print the branch root."""
693
b = Branch.open_containing(filename)
695
b = Branch.open_containing(filename)[0]
733
735
direction = (forward and 'forward') or 'reverse'
736
b = Branch.open_containing(filename)
737
tree = WorkingTree(b.base, b)
738
fp = tree.relpath(filename)
738
b, fp = Branch.open_containing(filename)
740
740
file_id = b.read_working_inventory().path2id(fp)
742
742
file_id = None # points to branch root
744
b = Branch.open_containing('.')
744
b, relpath = Branch.open_containing('.')
747
747
if revision is None:
795
795
takes_args = ["filename"]
796
796
def run(self, filename):
797
b = Branch.open_containing(filename)
797
b, relpath = Branch.open_containing(filename)[0]
798
798
inv = b.read_working_inventory()
799
tree = WorkingTree(b.base, b)
800
file_id = inv.path2id(tree.relpath(filename))
799
file_id = inv.path2id(relpath)
801
800
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
802
801
print "%6d %s" % (revno, what)
808
807
# TODO: Take a revision or remote path and list that tree instead.
810
809
def run(self, revision=None, verbose=False):
811
b = Branch.open_containing('.')
810
b, relpath = Branch.open_containing('.')[0]
812
811
if revision == None:
813
812
tree = b.working_tree()
897
896
See also: bzr ignore"""
899
tree = Branch.open_containing('.').working_tree()
898
tree = Branch.open_containing('.')[0].working_tree()
900
899
for path, file_class, kind, file_id, entry in tree.list_files():
901
900
if file_class != 'I':
939
938
takes_options = ['revision', 'format', 'root']
940
939
def run(self, dest, revision=None, format=None, root=None):
942
b = Branch.open_containing('.')
941
b = Branch.open_containing('.')[0]
943
942
if revision is None:
944
943
rev_id = b.last_revision()
978
977
raise BzrCommandError("bzr cat requires a revision number")
979
978
elif len(revision) != 1:
980
979
raise BzrCommandError("bzr cat --revision takes exactly one number")
981
b = Branch.open_containing('.')
982
tree = WorkingTree(b.base, b)
983
b.print_file(tree.relpath(filename), revision[0].in_history(b).revno)
980
b, relpath = Branch.open_containing(filename)
981
b.print_file(relpath, revision[0].in_history(b).revno)
986
984
class cmd_local_time_offset(Command):
1007
1005
# TODO: Run hooks on tree to-be-committed, and after commit.
1009
# TODO: Strict commit that fails if there are unknown or deleted files.
1007
# TODO: Strict commit that fails if there are deleted files.
1008
# (what does "deleted files" mean ??)
1010
1010
# TODO: Give better message for -s, --summary, used by tla people
1012
1012
# XXX: verbose currently does nothing
1018
1018
Option('file', type=str,
1019
1019
argname='msgfile',
1020
1020
help='file containing commit message'),
1022
help="refuse to commit if there are unknown "
1023
"files in the working tree."),
1022
1025
aliases = ['ci', 'checkin']
1024
1027
def run(self, message=None, file=None, verbose=True, selected_list=None,
1026
from bzrlib.errors import PointlessCommit, ConflictsInTree
1028
unchanged=False, strict=False):
1029
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1027
1031
from bzrlib.msgeditor import edit_commit_message
1028
1032
from bzrlib.status import show_status
1029
1033
from cStringIO import StringIO
1031
b = Branch.open_containing('.')
1035
b = Branch.open_containing('.')[0]
1032
1036
tree = WorkingTree(b.base, b)
1033
1037
if selected_list:
1034
1038
selected_list = [tree.relpath(s) for s in selected_list]
1052
1056
raise BzrCommandError("empty commit message specified")
1056
specific_files=selected_list,
1057
allow_pointless=unchanged)
1059
b.commit(message, specific_files=selected_list,
1060
allow_pointless=unchanged, strict=strict)
1058
1061
except PointlessCommit:
1059
1062
# FIXME: This should really happen before the file is read in;
1060
1063
# perhaps prepare the commit; get the message; then actually commit
1063
1066
except ConflictsInTree:
1064
1067
raise BzrCommandError("Conflicts detected in working tree. "
1065
1068
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1069
except StrictCommitFailed:
1070
raise BzrCommandError("Commit refused because there are unknown "
1071
"files in the working tree.")
1068
1074
class cmd_check(Command):
1077
1083
def run(self, dir='.', verbose=False):
1078
1084
from bzrlib.check import check
1079
check(Branch.open_containing(dir), verbose)
1085
check(Branch.open_containing(dir)[0], verbose)
1082
1088
class cmd_scan_cache(Command):
1122
1128
def run(self, email=False):
1124
b = bzrlib.branch.Branch.open_containing('.')
1130
b = bzrlib.branch.Branch.open_containing('.')[0]
1125
1131
config = bzrlib.config.BranchConfig(b)
1126
1132
except NotBranchError:
1127
1133
config = bzrlib.config.GlobalConfig()
1213
1219
def run(self, branch, other):
1214
1220
from bzrlib.revision import common_ancestor, MultipleRevisionSources
1216
branch1 = Branch.open_containing(branch)
1217
branch2 = Branch.open_containing(other)
1222
branch1 = Branch.open_containing(branch)[0]
1223
branch2 = Branch.open_containing(other)[0]
1219
1225
history_1 = branch1.revision_history()
1220
1226
history_2 = branch2.revision_history()
1335
1341
elif len(revision) != 1:
1336
1342
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1338
b = Branch.open_containing('.')
1344
b = Branch.open_containing('.')[0]
1339
1345
revno = revision[0].in_history(b).revno
1340
1346
merge(('.', revno), parse_spec('.'),
1341
1347
check_clean=False,
1428
1434
# We only update parent if it did not exist, missing
1429
1435
# should not change the parent
1430
1436
b.set_parent(remote)
1431
br_remote = Branch.open_containing(remote)
1437
br_remote = Branch.open_containing(remote)[0]
1432
1438
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1457
1463
takes_args = ['branch?']
1458
1464
def run(self, branch='.', revision=None, long=False):
1459
1465
from bzrlib.testament import Testament
1460
b = Branch.open_containing(branch)
1466
b = Branch.open_containing(branch)[0]
1463
1469
if revision is None:
1495
1501
def run(self, filename, all=False, long=False):
1496
1502
from bzrlib.annotate import annotate_file
1497
b = Branch.open_containing(filename)
1503
b, relpath = Branch.open_containing(filename)
1500
1506
tree = WorkingTree(b.base, b)
1501
rp = tree.relpath(filename)
1502
1507
tree = b.revision_tree(b.last_revision())
1503
file_id = tree.inventory.path2id(rp)
1508
file_id = tree.inventory.path2id(relpath)
1504
1509
file_version = tree.inventory[file_id].revision
1505
1510
annotate_file(b, file_version, file_id, long, all, sys.stdout)
1515
class cmd_re_sign(Command):
1516
"""Create a digital signature for an existing revision."""
1517
# TODO be able to replace existing ones.
1519
hidden = True # is this right ?
1520
takes_args = ['revision_id?']
1521
takes_options = ['revision']
1523
def run(self, revision_id=None, revision=None):
1524
import bzrlib.config as config
1525
import bzrlib.gpg as gpg
1526
if revision_id is not None and revision is not None:
1527
raise BzrCommandError('You can only supply one of revision_id or --revision')
1528
if revision_id is None and revision is None:
1529
raise BzrCommandError('You must supply either --revision or a revision_id')
1530
b = Branch.open_containing('.')[0]
1531
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
1532
if revision_id is not None:
1533
b.sign_revision(revision_id, gpg_strategy)
1534
elif revision is not None:
1535
for rev in revision:
1537
raise BzrCommandError('You cannot specify a NULL revision.')
1538
revno, rev_id = rev.in_history(b)
1539
b.sign_revision(rev_id, gpg_strategy)
1509
1542
# these get imported and then picked up by the scan for cmd_*
1510
1543
# TODO: Some more consistent way to split command definitions across files;
1511
1544
# we do need to load at least some information about them to know of