27
30
from bzrlib.commands import Command, display_command
28
31
from bzrlib.branch import Branch
29
32
from bzrlib.revision import common_ancestor
33
import bzrlib.errors as errors
30
34
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
31
35
NotBranchError, DivergedBranches, NotConflicted,
32
NoSuchFile, NoWorkingTree, FileInWrongBranch)
36
NoSuchFile, NoWorkingTree, FileInWrongBranch)
33
37
from bzrlib.option import Option
34
38
from bzrlib.revisionspec import RevisionSpec
35
39
import bzrlib.trace
36
from bzrlib.trace import mutter, note, log_error, warning
40
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
37
41
from bzrlib.workingtree import WorkingTree
40
def branch_files(file_list, default_branch='.'):
42
from bzrlib.log import show_one_log
45
def tree_files(file_list, default_branch=u'.'):
42
return inner_branch_files(file_list, default_branch)
47
return internal_tree_files(file_list, default_branch)
43
48
except FileInWrongBranch, e:
44
49
raise BzrCommandError("%s is not in the same branch as %s" %
45
50
(e.path, file_list[0]))
47
def inner_branch_files(file_list, default_branch='.'):
52
def internal_tree_files(file_list, default_branch=u'.'):
49
54
Return a branch and list of branch-relative paths.
50
55
If supplied file_list is empty or None, the branch default will be used,
51
56
and returned file_list will match the original.
53
58
if file_list is None or len(file_list) == 0:
54
return Branch.open_containing(default_branch)[0], file_list
55
b = Branch.open_containing(file_list[0])[0]
57
# note that if this is a remote branch, we would want
58
# relpath against the transport. RBC 20051018
59
# Most branch ops can't meaningfully operate on files in remote branches;
60
# the above comment was in cmd_status. ADHB 20051026
61
tree = WorkingTree(b.base, b)
59
return WorkingTree.open_containing(default_branch)[0], file_list
60
tree = WorkingTree.open_containing(file_list[0])[0]
63
62
for filename in file_list:
65
64
new_list.append(tree.relpath(filename))
66
except NotBranchError:
67
raise FileInWrongBranch(b, filename)
65
except errors.PathNotChild:
66
raise FileInWrongBranch(tree.branch, filename)
71
70
# TODO: Make sure no commands unconditionally use the working directory as a
124
123
def run(self, all=False, show_ids=False, file_list=None, revision=None):
125
b, file_list = branch_files(file_list)
124
tree, file_list = tree_files(file_list)
127
126
from bzrlib.status import show_status
128
show_status(b, show_unchanged=all, show_ids=show_ids,
127
show_status(tree.branch, show_unchanged=all, show_ids=show_ids,
129
128
specific_files=file_list, revision=revision)
147
146
raise BzrCommandError('You can only supply one of revision_id or --revision')
148
147
if revision_id is None and revision is None:
149
148
raise BzrCommandError('You must supply either --revision or a revision_id')
150
b = Branch.open_containing('.')[0]
149
b = WorkingTree.open_containing(u'.')[0].branch
151
150
if revision_id is not None:
152
sys.stdout.write(b.get_revision_xml_file(revision_id).read())
151
sys.stdout.write(b.get_revision_xml(revision_id))
153
152
elif revision is not None:
154
153
for rev in revision:
156
155
raise BzrCommandError('You cannot specify a NULL revision.')
157
156
revno, rev_id = rev.in_history(b)
158
sys.stdout.write(b.get_revision_xml_file(rev_id).read())
157
sys.stdout.write(b.get_revision_xml(rev_id))
161
160
class cmd_revno(Command):
162
161
"""Show current revision number.
164
163
This is equal to the number of revisions on this branch."""
164
takes_args = ['location?']
167
print Branch.open_containing('.')[0].revno()
166
def run(self, location=u'.'):
167
print Branch.open_containing(location)[0].revno()
170
170
class cmd_revision_info(Command):
217
217
implicitly add the parent, and so on up to the root. This means
218
218
you should never need to explictly add a directory, they'll just
219
219
get added when you add a file in the directory.
221
--dry-run will show which files would be added, but not actually
221
224
takes_args = ['file*']
222
takes_options = ['no-recurse', 'quiet']
224
def run(self, file_list, no_recurse=False, quiet=False):
225
from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
227
reporter = add_reporter_null
225
takes_options = ['no-recurse', 'dry-run', 'verbose']
227
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
232
# This is pointless, but I'd rather not raise an error
233
action = bzrlib.add.add_action_null
235
action = bzrlib.add.add_action_print
237
action = bzrlib.add.add_action_add
229
reporter = add_reporter_print
230
smart_add(file_list, not no_recurse, reporter)
239
action = bzrlib.add.add_action_add_and_print
241
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
244
for glob in sorted(ignored.keys()):
245
match_len = len(ignored[glob])
247
for path in ignored[glob]:
248
print "ignored %s matching \"%s\"" % (path, glob)
250
print "ignored %d file(s) matching \"%s\"" % (match_len,
252
print "If you wish to add some of these files, please add them"\
233
256
class cmd_mkdir(Command):
270
291
def run(self, revision=None, show_ids=False, kind=None):
271
292
if kind and kind not in ['file', 'directory', 'symlink']:
272
293
raise BzrCommandError('invalid kind specified')
273
b = Branch.open_containing('.')[0]
294
tree = WorkingTree.open_containing(u'.')[0]
274
295
if revision is None:
275
inv = b.working_tree().read_working_inventory()
296
inv = tree.read_working_inventory()
277
298
if len(revision) > 1:
278
299
raise BzrCommandError('bzr inventory --revision takes'
279
300
' exactly one revision identifier')
280
inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
301
inv = tree.branch.get_revision_inventory(
302
revision[0].in_history(tree.branch).rev_id)
282
304
for path, entry in inv.entries():
283
305
if kind and kind != entry.kind:
299
321
takes_args = ['source$', 'dest']
300
322
def run(self, source_list, dest):
301
b, source_list = branch_files(source_list)
323
tree, source_list = tree_files(source_list)
303
324
# TODO: glob expansion on windows?
304
tree = WorkingTree(b.base, b)
305
b.move(source_list, tree.relpath(dest))
325
tree.move(source_list, tree.relpath(dest))
308
328
class cmd_rename(Command):
322
342
takes_args = ['from_name', 'to_name']
324
344
def run(self, from_name, to_name):
325
b, (from_name, to_name) = branch_files((from_name, to_name))
326
b.rename_one(from_name, to_name)
345
tree, (from_name, to_name) = tree_files((from_name, to_name))
346
tree.rename_one(from_name, to_name)
329
349
class cmd_mv(Command):
343
363
def run(self, names_list):
344
364
if len(names_list) < 2:
345
365
raise BzrCommandError("missing file argument")
346
b, rel_names = branch_files(names_list)
366
tree, rel_names = tree_files(names_list)
348
368
if os.path.isdir(names_list[-1]):
349
369
# move into existing directory
350
for pair in b.move(rel_names[:-1], rel_names[-1]):
370
for pair in tree.move(rel_names[:-1], rel_names[-1]):
351
371
print "%s => %s" % pair
353
373
if len(names_list) != 2:
354
374
raise BzrCommandError('to mv multiple files the destination '
355
375
'must be a versioned directory')
356
b.rename_one(rel_names[0], rel_names[1])
376
tree.rename_one(rel_names[0], rel_names[1])
357
377
print "%s => %s" % (rel_names[0], rel_names[1])
382
402
from bzrlib.merge import merge
383
403
from shutil import rmtree
386
br_to = Branch.open_containing('.')[0]
387
stored_loc = br_to.get_parent()
405
# FIXME: too much stuff is in the command class
406
tree_to = WorkingTree.open_containing(u'.')[0]
407
stored_loc = tree_to.branch.get_parent()
388
408
if location is None:
389
409
if stored_loc is None:
390
410
raise BzrCommandError("No pull location known or specified.")
392
412
print "Using saved location: %s" % stored_loc
393
413
location = stored_loc
394
415
br_from = Branch.open(location)
396
old_rh = br_to.revision_history()
397
br_to.working_tree().pull(br_from, overwrite)
398
except DivergedBranches:
399
raise BzrCommandError("These branches have diverged."
416
br_to = tree_to.branch
418
old_rh = br_to.revision_history()
419
count = tree_to.pull(br_from, overwrite)
401
421
if br_to.get_parent() is None or remember:
402
422
br_to.set_parent(location)
423
note('%d revision(s) pulled.' % (count,))
405
new_rh = br_to.revision_history()
426
new_rh = tree_to.branch.revision_history()
406
427
if old_rh != new_rh:
407
428
# Something changed
408
429
from bzrlib.log import show_changed_revisions
409
show_changed_revisions(br_to, old_rh, new_rh)
430
show_changed_revisions(tree_to.branch, old_rh, new_rh)
412
433
class cmd_push(Command):
441
462
def run(self, location=None, remember=False, overwrite=False,
442
463
create_prefix=False, verbose=False):
464
# FIXME: Way too big! Put this into a function called from the
444
467
from shutil import rmtree
445
468
from bzrlib.transport import get_transport
447
br_from = Branch.open_containing('.')[0]
448
stored_loc = br_from.get_push_location()
470
tree_from = WorkingTree.open_containing(u'.')[0]
471
br_from = tree_from.branch
472
stored_loc = tree_from.branch.get_push_location()
449
473
if location is None:
450
474
if stored_loc is None:
451
475
raise BzrCommandError("No push location known or specified.")
478
502
if new_transport.base == transport.base:
479
503
raise BzrCommandError("Could not creeate "
483
505
br_to = Branch.initialize(location)
506
old_rh = br_to.revision_history()
485
old_rh = br_to.revision_history()
486
br_to.pull(br_from, overwrite)
509
tree_to = br_to.working_tree()
510
except NoWorkingTree:
511
# TODO: This should be updated for branches which don't have a
512
# working tree, as opposed to ones where we just couldn't
514
warning('Unable to update the working tree of: %s' % (br_to.base,))
515
count = br_to.pull(br_from, overwrite)
517
count = tree_to.pull(br_from, overwrite)
487
518
except DivergedBranches:
488
519
raise BzrCommandError("These branches have diverged."
489
520
" Try a merge then push with overwrite.")
490
521
if br_from.get_push_location() is None or remember:
491
522
br_from.set_push_location(location)
523
note('%d revision(s) pushed.' % (count,))
494
526
new_rh = br_to.revision_history()
749
786
b, file1 = Branch.open_containing(file_list[0])
750
787
b2, file2 = Branch.open_containing(file_list[1])
751
788
if file1 != "" or file2 != "":
789
# FIXME diff those two files. rbc 20051123
752
790
raise BzrCommandError("Files are in different branches")
754
792
if revision is not None:
755
793
if b2 is not None:
756
794
raise BzrCommandError("Can't specify -r with two branches")
757
if len(revision) == 1:
758
return show_diff(b, revision[0], specific_files=file_list,
795
if (len(revision) == 1) or (revision[1].spec is None):
796
return show_diff(tree.branch, revision[0], specific_files=file_list,
759
797
external_diff_options=diff_options)
760
798
elif len(revision) == 2:
761
return show_diff(b, revision[0], specific_files=file_list,
799
return show_diff(tree.branch, revision[0], specific_files=file_list,
762
800
external_diff_options=diff_options,
763
801
revision2=revision[1])
765
803
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
767
return show_diff(b, None, specific_files=file_list,
768
external_diff_options=diff_options, b2=b2)
806
return show_diff(b, None, specific_files=file_list,
807
external_diff_options=diff_options, b2=b2)
809
return show_diff(tree.branch, None, specific_files=file_list,
810
external_diff_options=diff_options)
771
813
class cmd_deleted(Command):
779
821
# if the directories are very large...)
781
823
def run(self, show_ids=False):
782
b = Branch.open_containing('.')[0]
784
new = b.working_tree()
824
tree = WorkingTree.open_containing(u'.')[0]
825
old = tree.branch.basis_tree()
785
826
for path, ie in old.inventory.iter_entries():
786
if not new.has_id(ie.file_id):
827
if not tree.has_id(ie.file_id):
788
829
print '%-50s %s' % (path, ie.file_id)
876
915
direction = (forward and 'forward') or 'reverse'
879
b, fp = Branch.open_containing(filename)
921
tree, fp = WorkingTree.open_containing(filename)
924
inv = tree.read_working_inventory()
925
except NotBranchError:
928
b, fp = Branch.open_containing(filename)
930
inv = b.get_inventory(b.last_revision())
882
inv = b.working_tree().read_working_inventory()
883
except NoWorkingTree:
884
inv = b.get_inventory(b.last_revision())
885
932
file_id = inv.path2id(fp)
887
934
file_id = None # points to branch root
889
b, relpath = Branch.open_containing('.')
936
tree, relpath = WorkingTree.open_containing(u'.')
892
940
if revision is None:
941
994
takes_args = ["filename"]
943
996
def run(self, filename):
944
b, relpath = Branch.open_containing(filename)[0]
945
inv = b.working_tree().read_working_inventory()
997
tree, relpath = WorkingTree.open_containing(filename)
999
inv = tree.read_working_inventory()
946
1000
file_id = inv.path2id(relpath)
947
1001
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
948
1002
print "%6d %s" % (revno, what)
977
1031
selection = {'I':ignored, '?':unknown, 'V':versioned}
979
b, relpath = Branch.open_containing('.')
1033
tree, relpath = WorkingTree.open_containing(u'.')
985
tree = b.working_tree()
987
tree = b.revision_tree(revision[0].in_history(b).rev_id)
1038
if revision is not None:
1039
tree = tree.branch.revision_tree(
1040
revision[0].in_history(tree.branch).rev_id)
988
1041
for fp, fc, kind, fid, entry in tree.list_files():
989
1042
if fp.startswith(relpath):
990
1043
fp = fp[len(relpath):]
1118
1168
is found exports to a directory (equivalent to --format=dir).
1120
1170
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."""
1122
# TODO: list known exporters
1171
is given, the top directory will be the root name of the file.
1173
Note: export of tree with non-ascii filenames to zip is not supported.
1175
Supported formats Autodetected by extension
1176
----------------- -------------------------
1179
tbz2 .tar.bz2, .tbz2
1123
1183
takes_args = ['dest']
1124
1184
takes_options = ['revision', 'format', 'root']
1125
1185
def run(self, dest, revision=None, format=None, root=None):
1127
b = Branch.open_containing('.')[0]
1187
from bzrlib.export import export
1188
tree = WorkingTree.open_containing(u'.')[0]
1128
1190
if revision is None:
1191
# should be tree.last_revision FIXME
1129
1192
rev_id = b.last_revision()
1131
1194
if len(revision) != 1:
1132
1195
raise BzrError('bzr export --revision takes exactly 1 argument')
1133
1196
rev_id = revision[0].in_history(b).rev_id
1134
1197
t = b.revision_tree(rev_id)
1135
arg_root, ext = os.path.splitext(os.path.basename(dest))
1136
if ext in ('.gz', '.bz2'):
1137
new_root, new_ext = os.path.splitext(arg_root)
1138
if new_ext == '.tar':
1144
if ext in (".tar",):
1146
elif ext in (".tar.gz", ".tgz"):
1148
elif ext in (".tar.bz2", ".tbz2"):
1152
t.export(dest, format, root)
1199
export(t, dest, format, root)
1200
except errors.NoSuchExportFormat, e:
1201
raise BzrCommandError('Unsupported export format: %s' % e.format)
1155
1204
class cmd_cat(Command):
1161
1210
@display_command
1162
1211
def run(self, filename, revision=None):
1163
if revision is None:
1164
raise BzrCommandError("bzr cat requires a revision number")
1165
elif len(revision) != 1:
1212
if revision is not None and len(revision) != 1:
1166
1213
raise BzrCommandError("bzr cat --revision takes exactly one number")
1167
b, relpath = Branch.open_containing(filename)
1168
b.print_file(relpath, revision[0].in_history(b).revno)
1216
tree, relpath = WorkingTree.open_containing(filename)
1218
except NotBranchError:
1222
b, relpath = Branch.open_containing(filename)
1223
if revision is None:
1224
revision_id = b.last_revision()
1226
revision_id = revision[0].in_history(b).rev_id
1227
b.print_file(relpath, revision_id)
1171
1230
class cmd_local_time_offset(Command):
1216
1275
unchanged=False, strict=False):
1217
1276
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1218
1277
StrictCommitFailed)
1219
from bzrlib.msgeditor import edit_commit_message
1278
from bzrlib.msgeditor import edit_commit_message, \
1279
make_commit_message_template
1220
1280
from bzrlib.status import show_status
1221
from cStringIO import StringIO
1223
b, selected_list = branch_files(selected_list)
1281
from tempfile import TemporaryFile
1284
# TODO: Need a blackbox test for invoking the external editor; may be
1285
# slightly problematic to run this cross-platform.
1287
# TODO: do more checks that the commit will succeed before
1288
# spending the user's valuable time typing a commit message.
1290
# TODO: if the commit *does* happen to fail, then save the commit
1291
# message to a temporary file where it can be recovered
1292
tree, selected_list = tree_files(selected_list)
1224
1293
if message is None and not file:
1225
catcher = StringIO()
1226
show_status(b, specific_files=selected_list,
1228
message = edit_commit_message(catcher.getvalue())
1294
template = make_commit_message_template(tree, selected_list)
1295
message = edit_commit_message(template)
1230
1296
if message is None:
1231
1297
raise BzrCommandError("please specify a commit message"
1232
1298
" with either --message or --file")
1241
1307
raise BzrCommandError("empty commit message specified")
1244
b.working_tree().commit(message, specific_files=selected_list,
1245
allow_pointless=unchanged, strict=strict)
1310
tree.commit(message, specific_files=selected_list,
1311
allow_pointless=unchanged, strict=strict)
1246
1312
except PointlessCommit:
1247
1313
# FIXME: This should really happen before the file is read in;
1248
1314
# perhaps prepare the commit; get the message; then actually commit
1262
1329
This command checks various invariants about the branch storage to
1263
1330
detect data corruption or bzr bugs.
1265
takes_args = ['dir?']
1332
takes_args = ['branch?']
1266
1333
takes_options = ['verbose']
1268
def run(self, dir='.', verbose=False):
1335
def run(self, branch=None, verbose=False):
1269
1336
from bzrlib.check import check
1270
check(Branch.open_containing(dir)[0], verbose)
1338
tree = WorkingTree.open_containing()[0]
1339
branch = tree.branch
1341
branch = Branch.open(branch)
1342
check(branch, verbose)
1273
1345
class cmd_scan_cache(Command):
1389
1461
bzrlib.ui.ui_factory = save_ui
1464
def _get_bzr_branch():
1465
"""If bzr is run from a branch, return Branch or None"""
1466
import bzrlib.errors
1467
from bzrlib.branch import Branch
1468
from bzrlib.osutils import abspath
1469
from os.path import dirname
1472
branch = Branch.open(dirname(abspath(dirname(__file__))))
1474
except bzrlib.errors.BzrError:
1392
1478
def show_version():
1393
1479
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1394
1480
# is bzrlib itself in a branch?
1395
bzrrev = bzrlib.get_bzr_revision()
1397
print " (bzr checkout, revision %d {%s})" % bzrrev
1481
branch = _get_bzr_branch()
1483
rh = branch.revision_history()
1485
print " bzr checkout, revision %d" % (revno,)
1486
print " nick: %s" % (branch.nick,)
1488
print " revid: %s" % (rh[-1],)
1398
1489
print bzrlib.__copyright__
1399
1490
print "http://bazaar-ng.org/"
1552
1643
from bzrlib.merge_core import ApplyMerge3
1553
1644
if merge_type is None:
1554
1645
merge_type = ApplyMerge3
1555
b, file_list = branch_files(file_list)
1646
tree, file_list = tree_files(file_list)
1558
pending_merges = b.working_tree().pending_merges()
1649
pending_merges = tree.pending_merges()
1559
1650
if len(pending_merges) != 1:
1560
1651
raise BzrCommandError("Sorry, remerge only works after normal"
1561
1652
+ " merges. Not cherrypicking or"
1562
1653
+ "multi-merges.")
1563
this_tree = b.working_tree()
1564
base_revision = common_ancestor(b.last_revision(),
1565
pending_merges[0], b)
1566
base_tree = b.revision_tree(base_revision)
1567
other_tree = b.revision_tree(pending_merges[0])
1654
base_revision = common_ancestor(tree.branch.last_revision(),
1655
pending_merges[0], tree.branch)
1656
base_tree = tree.branch.revision_tree(base_revision)
1657
other_tree = tree.branch.revision_tree(pending_merges[0])
1568
1658
interesting_ids = None
1569
1659
if file_list is not None:
1570
1660
interesting_ids = set()
1571
1661
for filename in file_list:
1572
file_id = this_tree.path2id(filename)
1662
file_id = tree.path2id(filename)
1573
1663
interesting_ids.add(file_id)
1574
if this_tree.kind(file_id) != "directory":
1664
if tree.kind(file_id) != "directory":
1577
for name, ie in this_tree.inventory.iter_entries(file_id):
1667
for name, ie in tree.inventory.iter_entries(file_id):
1578
1668
interesting_ids.add(ie.file_id)
1579
transform_tree(this_tree, b.basis_tree(), interesting_ids)
1669
transform_tree(tree, tree.branch.basis_tree(), interesting_ids)
1580
1670
if file_list is None:
1581
restore_files = list(this_tree.iter_conflicts())
1671
restore_files = list(tree.iter_conflicts())
1583
1673
restore_files = file_list
1584
1674
for filename in restore_files:
1586
restore(this_tree.abspath(filename))
1676
restore(tree.abspath(filename))
1587
1677
except NotConflicted:
1589
conflicts = merge_inner(b, other_tree, base_tree,
1679
conflicts = merge_inner(tree.branch, other_tree, base_tree,
1590
1680
interesting_ids = interesting_ids,
1591
1681
other_rev_id=pending_merges[0],
1592
1682
merge_type=merge_type,
1593
1683
show_base=show_base,
1594
1684
reprocess=reprocess)
1597
1687
if conflicts > 0:
1621
1711
if revision is None:
1623
b = Branch.open_containing('.')[0]
1624
rev_id = b.last_revision()
1713
tree = WorkingTree.open_containing(u'.')[0]
1714
# FIXME should be tree.last_revision
1715
rev_id = tree.branch.last_revision()
1625
1716
elif len(revision) != 1:
1626
1717
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1628
b, file_list = branch_files(file_list)
1629
rev_id = revision[0].in_history(b).rev_id
1630
b.working_tree().revert(file_list, b.revision_tree(rev_id),
1719
tree, file_list = tree_files(file_list)
1720
rev_id = revision[0].in_history(tree.branch).rev_id
1721
tree.revert(file_list, tree.branch.revision_tree(rev_id),
1693
1784
class cmd_missing(Command):
1694
"""What is missing in this branch relative to other branch.
1696
# TODO: rewrite this in terms of ancestry so that it shows only
1699
takes_args = ['remote?']
1700
aliases = ['mis', 'miss']
1701
# We don't have to add quiet to the list, because
1702
# unknown options are parsed as booleans
1703
takes_options = ['verbose', 'quiet']
1706
def run(self, remote=None, verbose=False, quiet=False):
1707
from bzrlib.errors import BzrCommandError
1708
from bzrlib.missing import show_missing
1710
if verbose and quiet:
1711
raise BzrCommandError('Cannot pass both quiet and verbose')
1713
b = Branch.open_containing('.')[0]
1714
parent = b.get_parent()
1785
"""Show unmerged/unpulled revisions between two branches.
1787
OTHER_BRANCH may be local or remote."""
1788
takes_args = ['other_branch?']
1789
takes_options = [Option('reverse', 'Reverse the order of revisions'),
1791
'Display changes in the local branch only'),
1792
Option('theirs-only',
1793
'Display changes in the remote branch only'),
1801
def run(self, other_branch=None, reverse=False, mine_only=False,
1802
theirs_only=False, long=True, short=False, line=False,
1803
show_ids=False, verbose=False):
1804
from bzrlib.missing import find_unmerged, iter_log_data
1805
from bzrlib.log import log_formatter
1806
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
1807
parent = local_branch.get_parent()
1808
if other_branch is None:
1809
other_branch = parent
1810
if other_branch is None:
1717
1811
raise BzrCommandError("No missing location known or specified.")
1720
print "Using last location: %s" % parent
1722
elif parent is None:
1723
# We only update parent if it did not exist, missing
1724
# should not change the parent
1725
b.set_parent(remote)
1726
br_remote = Branch.open_containing(remote)[0]
1727
return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
1812
print "Using last location: " + local_branch.get_parent()
1813
remote_branch = bzrlib.branch.Branch.open(other_branch)
1814
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
1815
log_format = get_log_format(long=long, short=short, line=line)
1816
lf = log_formatter(log_format, sys.stdout,
1818
show_timezone='original')
1819
if reverse is False:
1820
local_extra.reverse()
1821
remote_extra.reverse()
1822
if local_extra and not theirs_only:
1823
print "You have %d extra revision(s):" % len(local_extra)
1824
for data in iter_log_data(local_extra, local_branch, verbose):
1826
printed_local = True
1828
printed_local = False
1829
if remote_extra and not mine_only:
1830
if printed_local is True:
1832
print "You are missing %d revision(s):" % len(remote_extra)
1833
for data in iter_log_data(remote_extra, remote_branch, verbose):
1835
if not remote_extra and not local_extra:
1837
print "Branches are up to date."
1840
if parent is None and other_branch is not None:
1841
local_branch.set_parent(other_branch)
1730
1845
class cmd_plugins(Command):
1792
1907
@display_command
1793
1908
def run(self, filename, all=False, long=False):
1794
1909
from bzrlib.annotate import annotate_file
1795
b, relpath = Branch.open_containing(filename)
1910
tree, relpath = WorkingTree.open_containing(filename)
1911
branch = tree.branch
1798
tree = WorkingTree(b.base, b)
1799
tree = b.revision_tree(b.last_revision())
1800
1914
file_id = tree.inventory.path2id(relpath)
1915
tree = branch.revision_tree(branch.last_revision())
1801
1916
file_version = tree.inventory[file_id].revision
1802
annotate_file(b, file_version, file_id, long, all, sys.stdout)
1917
annotate_file(branch, file_version, file_id, long, all, sys.stdout)
1807
1922
class cmd_re_sign(Command):
1843
1958
raise BzrCommandError('Please supply either one revision, or a range.')
1961
class cmd_uncommit(bzrlib.commands.Command):
1962
"""Remove the last committed revision.
1964
By supplying the --all flag, it will not only remove the entry
1965
from revision_history, but also remove all of the entries in the
1968
--verbose will print out what is being removed.
1969
--dry-run will go through all the motions, but not actually
1972
In the future, uncommit will create a changeset, which can then
1975
TODO: jam 20060108 Add an option to allow uncommit to remove unreferenced
1976
information in 'branch-as-repostory' branches.
1977
TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
1978
information in shared branches as well.
1980
takes_options = ['verbose', 'revision',
1981
Option('dry-run', help='Don\'t actually make changes'),
1982
Option('force', help='Say yes to all questions.')]
1983
takes_args = ['location?']
1986
def run(self, location=None,
1987
dry_run=False, verbose=False,
1988
revision=None, force=False):
1989
from bzrlib.branch import Branch
1990
from bzrlib.log import log_formatter
1992
from bzrlib.uncommit import uncommit
1994
if location is None:
1996
b, relpath = Branch.open_containing(location)
1998
if revision is None:
2000
rev_id = b.last_revision()
2002
revno, rev_id = revision[0].in_history(b)
2004
print 'No revisions to uncommit.'
2006
for r in range(revno, b.revno()+1):
2007
rev_id = b.get_rev_id(r)
2008
lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2009
lf.show(r, b.get_revision(rev_id), None)
2012
print 'Dry-run, pretending to remove the above revisions.'
2014
val = raw_input('Press <enter> to continue')
2016
print 'The above revision(s) will be removed.'
2018
val = raw_input('Are you sure [y/N]? ')
2019
if val.lower() not in ('y', 'yes'):
2023
uncommit(b, dry_run=dry_run, verbose=verbose,
1846
2027
# these get imported and then picked up by the scan for cmd_*
1847
2028
# TODO: Some more consistent way to split command definitions across files;
1848
2029
# we do need to load at least some information about them to know of