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
31
from bzrlib.workingtree import WorkingTree
31
34
class cmd_status(Command):
32
35
"""Display status summary.
77
80
def run(self, all=False, show_ids=False, file_list=None, revision=None):
79
b = Branch.open_containing(file_list[0])
80
file_list = [b.relpath(x) for x in file_list]
81
# special case: only one path was given and it's the root
82
b, relpath = Branch.open_containing(file_list[0])
83
if relpath == '' and len(file_list) == 1:
86
# generate relative paths.
87
# note that if this is a remote branch, we would want
88
# relpath against the transport. RBC 20051018
89
tree = WorkingTree(b.base, b)
90
file_list = [tree.relpath(x) for x in file_list]
86
b = Branch.open_containing('.')
92
b = Branch.open_containing('.')[0]
88
94
from bzrlib.status import show_status
89
95
show_status(b, show_unchanged=all, show_ids=show_ids,
102
108
takes_options = ['revision']
104
110
def run(self, revision_id=None, revision=None):
105
from bzrlib.revisionspec import RevisionSpec
107
112
if revision_id is not None and revision is not None:
108
113
raise BzrCommandError('You can only supply one of revision_id or --revision')
109
114
if revision_id is None and revision is None:
110
115
raise BzrCommandError('You must supply either --revision or a revision_id')
111
b = Branch.open_containing('.')
116
b = Branch.open_containing('.')[0]
112
117
if revision_id is not None:
113
118
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
114
119
elif revision is not None:
250
254
takes_args = ['source$', 'dest']
251
255
def run(self, source_list, dest):
252
b = Branch.open_containing('.')
256
b = Branch.open_containing('.')[0]
254
258
# TODO: glob expansion on windows?
255
b.move([b.relpath(s) for s in source_list], b.relpath(dest))
259
tree = WorkingTree(b.base, b)
260
b.move([tree.relpath(s) for s in source_list], tree.relpath(dest))
258
263
class cmd_rename(Command):
272
277
takes_args = ['from_name', 'to_name']
274
279
def run(self, from_name, to_name):
275
b = Branch.open_containing('.')
276
b.rename_one(b.relpath(from_name), b.relpath(to_name))
280
b = Branch.open_containing('.')[0]
281
tree = WorkingTree(b.base, b)
282
b.rename_one(tree.relpath(from_name), tree.relpath(to_name))
280
285
class cmd_mv(Command):
294
299
def run(self, names_list):
295
300
if len(names_list) < 2:
296
301
raise BzrCommandError("missing file argument")
297
b = Branch.open_containing(names_list[0])
299
rel_names = [b.relpath(x) for x in names_list]
302
b = Branch.open_containing(names_list[0])[0]
303
tree = WorkingTree(b.base, b)
304
rel_names = [tree.relpath(x) for x in names_list]
301
306
if os.path.isdir(names_list[-1]):
302
307
# move into existing directory
326
331
If branches have diverged, you can use 'bzr merge' to pull the text changes
327
332
from one into the other.
329
takes_options = ['remember']
334
takes_options = ['remember', 'clobber']
330
335
takes_args = ['location?']
332
def run(self, location=None, remember=False):
337
def run(self, location=None, remember=False, clobber=False):
333
338
from bzrlib.merge import merge
335
340
from shutil import rmtree
338
br_to = Branch.open_containing('.')
343
br_to = Branch.open_containing('.')[0]
339
344
stored_loc = br_to.get_parent()
340
345
if location is None:
341
346
if stored_loc is None:
344
349
print "Using saved location: %s" % stored_loc
345
350
location = stored_loc
346
cache_root = tempfile.mkdtemp()
347
351
br_from = Branch.open(location)
350
br_from.setup_caching(cache_root)
351
location = br_from.base
352
old_revno = br_to.revno()
353
old_revision_history = br_to.revision_history()
355
br_to.update_revisions(br_from)
356
except DivergedBranches:
357
raise BzrCommandError("These branches have diverged."
359
new_revision_history = br_to.revision_history()
360
if new_revision_history != old_revision_history:
361
merge(('.', -1), ('.', old_revno), check_clean=False)
362
if stored_loc is None or remember:
363
br_to.set_parent(location)
353
br_to.working_tree().pull(br_from, remember, clobber)
354
except DivergedBranches:
355
raise BzrCommandError("These branches have diverged."
370
359
class cmd_branch(Command):
596
586
from bzrlib.diff import show_diff
599
b = Branch.open_containing(file_list[0])
600
file_list = [b.relpath(f) for f in file_list]
589
b = Branch.open_containing(file_list[0])[0]
590
tree = WorkingTree(b.base, b)
591
file_list = [tree.relpath(f) for f in file_list]
601
592
if file_list == ['']:
602
593
# just pointing to top-of-tree
605
b = Branch.open_containing('.')
596
b = Branch.open_containing('.')[0]
607
598
if revision is not None:
608
599
if len(revision) == 1:
718
712
from bzrlib.log import log_formatter, show_log
720
assert isinstance(message, basestring), \
714
assert message is None or isinstance(message, basestring), \
721
715
"invalid message argument %r" % message
722
716
direction = (forward and 'forward') or 'reverse'
725
b = Branch.open_containing(filename)
726
fp = b.relpath(filename)
719
b, fp = Branch.open_containing(filename)
728
721
file_id = b.read_working_inventory().path2id(fp)
730
723
file_id = None # points to branch root
732
b = Branch.open_containing('.')
725
b, relpath = Branch.open_containing('.')
735
728
if revision is None:
782
776
takes_args = ["filename"]
783
777
def run(self, filename):
784
b = Branch.open_containing(filename)
778
b, relpath = Branch.open_containing(filename)[0]
785
779
inv = b.read_working_inventory()
786
file_id = inv.path2id(b.relpath(filename))
780
file_id = inv.path2id(relpath)
787
781
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
788
782
print "%6d %s" % (revno, what)
1003
999
Option('file', type=str,
1004
1000
argname='msgfile',
1005
1001
help='file containing commit message'),
1003
help="refuse to commit if there are unknown "
1004
"files in the working tree."),
1007
1006
aliases = ['ci', 'checkin']
1009
1008
def run(self, message=None, file=None, verbose=True, selected_list=None,
1011
from bzrlib.errors import PointlessCommit, ConflictsInTree
1009
unchanged=False, strict=False):
1010
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1012
1012
from bzrlib.msgeditor import edit_commit_message
1013
1013
from bzrlib.status import show_status
1014
1014
from cStringIO import StringIO
1016
b = Branch.open_containing('.')
1016
b = Branch.open_containing('.')[0]
1017
tree = WorkingTree(b.base, b)
1017
1018
if selected_list:
1018
selected_list = [b.relpath(s) for s in selected_list]
1019
selected_list = [tree.relpath(s) for s in selected_list]
1020
1020
if message is None and not file:
1021
1021
catcher = StringIO()
1022
1022
show_status(b, specific_files=selected_list,
1127
1130
If arguments are given, they are regular expressions that say
1128
which tests should run."""
1131
which tests should run.
1129
1133
# TODO: --list should give a list of all available tests
1131
1135
takes_args = ['testspecs*']
1132
takes_options = ['verbose']
1133
def run(self, testspecs_list=None, verbose=False):
1136
takes_options = ['verbose',
1137
Option('one', help='stop when one test fails'),
1140
def run(self, testspecs_list=None, verbose=False, one=False):
1134
1141
import bzrlib.ui
1135
1142
from bzrlib.selftest import selftest
1136
1143
# we don't want progress meters from the tests to go to the
1192
1200
def run(self, branch, other):
1193
1201
from bzrlib.revision import common_ancestor, MultipleRevisionSources
1195
branch1 = Branch.open_containing(branch)
1196
branch2 = Branch.open_containing(other)
1203
branch1 = Branch.open_containing(branch)[0]
1204
branch2 = Branch.open_containing(other)[0]
1198
1206
history_1 = branch1.revision_history()
1199
1207
history_2 = branch2.revision_history()
1455
1463
class cmd_annotate(Command):
1456
1464
"""Show the origin of each line in a file.
1458
This prints out the given file with an annotation on the
1459
left side indicating which revision, author and date introduced the
1466
This prints out the given file with an annotation on the left side
1467
indicating which revision, author and date introduced the change.
1469
If the origin is the same for a run of consecutive lines, it is
1470
shown only at the top, unless the --all option is given.
1462
1472
# TODO: annotate directories; showing when each file was last changed
1463
1473
# TODO: annotate a previous version of a file
1474
# TODO: if the working copy is modified, show annotations on that
1475
# with new uncommitted lines marked
1464
1476
aliases = ['blame', 'praise']
1465
1477
takes_args = ['filename']
1478
takes_options = [Option('all', help='show annotations on all lines'),
1479
Option('long', help='show date in annotations'),
1467
def run(self, filename):
1482
def run(self, filename, all=False, long=False):
1468
1483
from bzrlib.annotate import annotate_file
1469
b = Branch.open_containing(filename)
1484
b, relpath = Branch.open_containing(filename)
1472
rp = b.relpath(filename)
1487
tree = WorkingTree(b.base, b)
1473
1488
tree = b.revision_tree(b.last_revision())
1474
file_id = tree.inventory.path2id(rp)
1489
file_id = tree.inventory.path2id(relpath)
1475
1490
file_version = tree.inventory[file_id].revision
1476
annotate_file(b, file_version, file_id, sys.stdout)
1491
annotate_file(b, file_version, file_id, long, all, sys.stdout)
1496
class cmd_re_sign(Command):
1497
"""Create a digital signature for an existing revision."""
1498
# TODO be able to replace existing ones.
1500
hidden = True # is this right ?
1501
takes_args = ['revision_id?']
1502
takes_options = ['revision']
1504
def run(self, revision_id=None, revision=None):
1505
import bzrlib.config as config
1506
import bzrlib.gpg as gpg
1507
if revision_id is not None and revision is not None:
1508
raise BzrCommandError('You can only supply one of revision_id or --revision')
1509
if revision_id is None and revision is None:
1510
raise BzrCommandError('You must supply either --revision or a revision_id')
1511
b = Branch.open_containing('.')[0]
1512
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
1513
if revision_id is not None:
1514
b.sign_revision(revision_id, gpg_strategy)
1515
elif revision is not None:
1516
for rev in revision:
1518
raise BzrCommandError('You cannot specify a NULL revision.')
1519
revno, rev_id = rev.in_history(b)
1520
b.sign_revision(rev_id, gpg_strategy)
1480
1523
# these get imported and then picked up by the scan for cmd_*
1481
1524
# TODO: Some more consistent way to split command definitions across files;
1482
1525
# we do need to load at least some information about them to know of