17
17
"""builtin bzr commands"""
22
from shutil import rmtree
27
from bzrlib.branch import Branch, BranchReferenceFormat
28
from bzrlib import (bundle, branch, bzrdir, errors, osutils, ui, config,
30
from bzrlib.bundle import read_bundle_from_url
31
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
32
from bzrlib.conflicts import ConflictList
27
from bzrlib.branch import Branch
28
import bzrlib.bzrdir as bzrdir
33
29
from bzrlib.commands import Command, display_command
30
from bzrlib.revision import common_ancestor
31
import bzrlib.errors as errors
34
32
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
35
33
NotBranchError, DivergedBranches, NotConflicted,
36
34
NoSuchFile, NoWorkingTree, FileInWrongBranch,
37
NotVersionedError, NotABundle)
36
from bzrlib.log import show_one_log
38
37
from bzrlib.merge import Merge3Merger
39
38
from bzrlib.option import Option
40
39
from bzrlib.progress import DummyProgress, ProgressPhase
41
from bzrlib.revision import common_ancestor
42
40
from bzrlib.revisionspec import RevisionSpec
43
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
42
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
44
43
from bzrlib.transport.local import LocalTransport
45
import bzrlib.urlutils as urlutils
46
45
from bzrlib.workingtree import WorkingTree
86
85
"""Parse and return a format specifier."""
87
86
if typestring == "weave":
88
87
return bzrdir.BzrDirFormat6()
89
if typestring == "default":
88
if typestring == "metadir":
90
89
return bzrdir.BzrDirMetaFormat1()
91
if typestring == "metaweave":
92
format = bzrdir.BzrDirMetaFormat1()
93
format.repository_format = repository.RepositoryFormat7()
95
90
if typestring == "knit":
96
91
format = bzrdir.BzrDirMetaFormat1()
97
format.repository_format = repository.RepositoryFormatKnit1()
92
format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
99
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
100
"metaweave and weave" % typestring
94
msg = "No known bzr-dir format %s. Supported types are: weave, metadir\n" %\
101
96
raise BzrCommandError(msg)
146
145
# TODO: --no-recurse, --recurse options
148
147
takes_args = ['file*']
149
takes_options = ['show-ids', 'revision']
148
takes_options = ['all', 'show-ids', 'revision']
150
149
aliases = ['st', 'stat']
152
encoding_type = 'replace'
155
def run(self, show_ids=False, file_list=None, revision=None):
152
def run(self, all=False, show_ids=False, file_list=None, revision=None):
153
tree, file_list = tree_files(file_list)
156
155
from bzrlib.status import show_tree_status
158
tree, file_list = tree_files(file_list)
160
show_tree_status(tree, show_ids=show_ids,
161
specific_files=file_list, revision=revision,
156
show_tree_status(tree, show_unchanged=all, show_ids=show_ids,
157
specific_files=file_list, revision=revision)
165
160
class cmd_cat_revision(Command):
183
176
if revision_id is None and revision is None:
184
177
raise BzrCommandError('You must supply either --revision or a revision_id')
185
178
b = WorkingTree.open_containing(u'.')[0].branch
187
# TODO: jam 20060112 should cat-revision always output utf-8?
188
179
if revision_id is not None:
189
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
180
sys.stdout.write(b.repository.get_revision_xml(revision_id))
190
181
elif revision is not None:
191
182
for rev in revision:
193
184
raise BzrCommandError('You cannot specify a NULL revision.')
194
185
revno, rev_id = rev.in_history(b)
195
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
186
sys.stdout.write(b.repository.get_revision_xml(rev_id))
198
189
class cmd_revno(Command):
199
190
"""Show current revision number.
201
This is equal to the number of revisions on this branch.
192
This is equal to the number of revisions on this branch."""
204
193
takes_args = ['location?']
207
195
def run(self, location=u'.'):
208
self.outf.write(str(Branch.open_containing(location)[0].revno()))
209
self.outf.write('\n')
196
print Branch.open_containing(location)[0].revno()
212
199
class cmd_revision_info(Command):
259
245
Adding a file whose parent directory is not versioned will
260
246
implicitly add the parent, and so on up to the root. This means
261
you should never need to explicitly add a directory, they'll just
247
you should never need to explictly add a directory, they'll just
262
248
get added when you add a file in the directory.
264
250
--dry-run will show which files would be added, but not actually
267
253
takes_args = ['file*']
268
254
takes_options = ['no-recurse', 'dry-run', 'verbose']
269
encoding_type = 'replace'
271
256
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
272
257
import bzrlib.add
274
action = bzrlib.add.AddAction(to_file=self.outf,
275
should_print=(not is_quiet()))
261
# This is pointless, but I'd rather not raise an error
262
action = bzrlib.add.add_action_null
264
action = bzrlib.add.add_action_print
266
action = bzrlib.add.add_action_add
268
action = bzrlib.add.add_action_add_and_print
277
270
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
278
action=action, save=not dry_run)
279
272
if len(ignored) > 0:
281
for glob in sorted(ignored.keys()):
273
for glob in sorted(ignored.keys()):
274
match_len = len(ignored[glob])
282
276
for path in ignored[glob]:
283
self.outf.write("ignored %s matching \"%s\"\n"
287
for glob, paths in ignored.items():
288
match_len += len(paths)
289
self.outf.write("ignored %d file(s).\n" % match_len)
290
self.outf.write("If you wish to add some of these files,"
291
" please add them by name.\n")
277
print "ignored %s matching \"%s\"" % (path, glob)
279
print "ignored %d file(s) matching \"%s\"" % (match_len,
281
print "If you wish to add some of these files, please add them"\
294
285
class cmd_mkdir(Command):
297
288
This is equivalent to creating the directory and then adding it.
300
290
takes_args = ['dir+']
301
encoding_type = 'replace'
303
292
def run(self, dir_list):
304
293
for d in dir_list:
306
295
wt, dd = WorkingTree.open_containing(d)
308
self.outf.write('added %s\n' % d)
311
300
class cmd_relpath(Command):
312
301
"""Show path of a file relative to root"""
314
302
takes_args = ['filename']
318
306
def run(self, filename):
319
# TODO: jam 20050106 Can relpath return a munged path if
320
# sys.stdout encoding cannot represent it?
321
307
tree, relpath = WorkingTree.open_containing(filename)
322
self.outf.write(relpath)
323
self.outf.write('\n')
326
311
class cmd_inventory(Command):
382
363
if os.path.isdir(names_list[-1]):
383
364
# move into existing directory
384
365
for pair in tree.move(rel_names[:-1], rel_names[-1]):
385
self.outf.write("%s => %s\n" % pair)
366
print "%s => %s" % pair
387
368
if len(names_list) != 2:
388
369
raise BzrCommandError('to mv multiple files the destination '
389
370
'must be a versioned directory')
390
371
tree.rename_one(rel_names[0], rel_names[1])
391
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
372
print "%s => %s" % (rel_names[0], rel_names[1])
394
375
class cmd_pull(Command):
402
383
from one into the other. Once one branch has merged, the other should
403
384
be able to pull it again.
386
If branches have diverged, you can use 'bzr merge' to pull the text changes
387
from one into the other. Once one branch has merged, the other should
388
be able to pull it again.
405
390
If you want to forget your local changes and just update your branch to
406
391
match the remote one, use pull --overwrite.
408
393
If there is no default location set, the first pull will set it. After
409
394
that, you can omit the location to use the default. To change the
410
default, use --remember. The value will only be saved if the remote
411
location can be accessed.
395
default, use --remember.
414
397
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
415
398
takes_args = ['location?']
416
encoding_type = 'replace'
418
400
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
419
401
# FIXME: too much stuff is in the command class
422
404
branch_to = tree_to.branch
423
405
except NoWorkingTree:
425
branch_to = Branch.open_containing(u'.')[0]
428
if location is not None:
430
reader = bundle.read_bundle_from_url(location)
432
pass # Continue on considering this url a Branch
407
branch_to = Branch.open_containing(u'.')[0]
434
408
stored_loc = branch_to.get_parent()
435
409
if location is None:
436
410
if stored_loc is None:
437
411
raise BzrCommandError("No pull location known or specified.")
439
display_url = urlutils.unescape_for_display(stored_loc,
441
self.outf.write("Using saved location: %s\n" % display_url)
413
print "Using saved location: %s" % stored_loc
442
414
location = stored_loc
445
if reader is not None:
446
install_bundle(branch_to.repository, reader)
447
branch_from = branch_to
449
branch_from = Branch.open(location)
451
if branch_to.get_parent() is None or remember:
452
branch_to.set_parent(branch_from.base)
416
if branch_to.get_parent() is None or remember:
417
branch_to.set_parent(location)
419
branch_from = Branch.open(location)
455
421
if revision is None:
456
if reader is not None:
457
rev_id = reader.target
458
423
elif len(revision) == 1:
459
424
rev_id = revision[0].in_history(branch_from).rev_id
499
463
If there is no default push location set, the first push will set it.
500
464
After that, you can omit the location to use the default. To change the
501
default, use --remember. The value will only be saved if the remote
502
location can be accessed.
465
default, use --remember.
505
takes_options = ['remember', 'overwrite', 'verbose',
467
takes_options = ['remember', 'overwrite',
506
468
Option('create-prefix',
507
469
help='Create the path leading up to the branch '
508
470
'if it does not already exist')]
509
471
takes_args = ['location?']
510
encoding_type = 'replace'
512
473
def run(self, location=None, remember=False, overwrite=False,
513
474
create_prefix=False, verbose=False):
516
477
from bzrlib.transport import get_transport
518
br_from = Branch.open_containing('.')[0]
519
stored_loc = br_from.get_push_location()
479
tree_from = WorkingTree.open_containing(u'.')[0]
480
br_from = tree_from.branch
481
stored_loc = tree_from.branch.get_push_location()
520
482
if location is None:
521
483
if stored_loc is None:
522
484
raise BzrCommandError("No push location known or specified.")
524
display_url = urlutils.unescape_for_display(stored_loc,
526
self.outf.write("Using saved location: %s\n" % display_url)
486
print "Using saved location: %s" % stored_loc
527
487
location = stored_loc
529
transport = get_transport(location)
530
location_url = transport.base
488
if br_from.get_push_location() is None or remember:
489
br_from.set_push_location(location)
534
dir_to = bzrdir.BzrDir.open(location_url)
491
dir_to = bzrlib.bzrdir.BzrDir.open(location)
535
492
br_to = dir_to.open_branch()
536
493
except NotBranchError:
537
494
# create a branch.
538
transport = transport.clone('..')
495
transport = get_transport(location).clone('..')
539
496
if not create_prefix:
541
relurl = transport.relpath(location_url)
542
mutter('creating directory %s => %s', location_url, relurl)
543
transport.mkdir(relurl)
498
transport.mkdir(transport.relpath(location))
544
499
except NoSuchFile:
545
500
raise BzrCommandError("Parent directory of %s "
546
501
"does not exist." % location)
548
503
current = transport.base
549
needed = [(transport, transport.relpath(location_url))]
504
needed = [(transport, transport.relpath(location))]
552
507
transport, relpath = needed[-1]
559
514
if new_transport.base == transport.base:
560
515
raise BzrCommandError("Could not create "
562
dir_to = br_from.bzrdir.clone(location_url,
563
revision_id=br_from.last_revision())
517
dir_to = br_from.bzrdir.clone(location)
564
518
br_to = dir_to.open_branch()
565
count = len(br_to.revision_history())
566
# We successfully created the target, remember it
567
if br_from.get_push_location() is None or remember:
568
br_from.set_push_location(br_to.base)
570
# We were able to connect to the remote location, so remember it
571
# we don't need to successfully push because of possible divergence.
572
if br_from.get_push_location() is None or remember:
573
br_from.set_push_location(br_to.base)
574
old_rh = br_to.revision_history()
519
old_rh = br_to.revision_history()
577
tree_to = dir_to.open_workingtree()
578
except errors.NotLocalUrl:
579
warning('This transport does not update the working '
580
'tree of: %s' % (br_to.base,))
581
count = br_to.pull(br_from, overwrite)
582
except NoWorkingTree:
583
count = br_to.pull(br_from, overwrite)
585
count = tree_to.pull(br_from, overwrite)
586
except DivergedBranches:
587
raise BzrCommandError("These branches have diverged."
588
" Try a merge then push with overwrite.")
522
tree_to = dir_to.open_workingtree()
523
except errors.NotLocalUrl:
524
# TODO: This should be updated for branches which don't have a
525
# working tree, as opposed to ones where we just couldn't
527
warning('This transport does not update the working '
528
'tree of: %s' % (br_to.base,))
529
count = br_to.pull(br_from, overwrite)
530
except NoWorkingTree:
531
count = br_to.pull(br_from, overwrite)
533
count = tree_to.pull(br_from, overwrite)
534
except DivergedBranches:
535
raise BzrCommandError("These branches have diverged."
536
" Try a merge then push with overwrite.")
589
537
note('%d revision(s) pushed.' % (count,))
649
595
name = os.path.basename(to_location) + '\n'
651
to_transport = get_transport(to_location)
653
to_transport.mkdir('.')
654
except errors.FileExists:
655
raise BzrCommandError('Target directory "%s" already'
656
' exists.' % to_location)
657
except errors.NoSuchFile:
658
raise BzrCommandError('Parent of "%s" does not exist.' %
597
os.mkdir(to_location)
599
if e.errno == errno.EEXIST:
600
raise BzrCommandError('Target directory "%s" already'
601
' exists.' % to_location)
602
if e.errno == errno.ENOENT:
603
raise BzrCommandError('Parent of "%s" does not exist.' %
661
608
# preserve whatever source format we have.
662
dir = br_from.bzrdir.sprout(to_transport.base,
663
revision_id, basis_dir)
609
dir = br_from.bzrdir.sprout(to_location, revision_id, basis_dir)
664
610
branch = dir.open_branch()
665
except errors.NoSuchRevision:
666
to_transport.delete_tree('.')
611
except bzrlib.errors.NoSuchRevision:
667
613
msg = "The branch %s has no revision %s." % (from_location, revision[0])
668
614
raise BzrCommandError(msg)
669
except errors.UnlistableBranch:
670
osutils.rmtree(to_location)
615
except bzrlib.errors.UnlistableBranch:
671
617
msg = "The branch %s cannot be used as a --basis" % (basis,)
672
618
raise BzrCommandError(msg)
674
620
branch.control_files.put_utf8('branch-name', name)
675
622
note('Branched %d revision(s).' % branch.revno())
696
643
--basis is to speed up checking out from remote branches. When specified, it
697
644
uses the inventory and file contents from the basis branch in preference to the
698
branch being checked out.
645
branch being checked out. [Not implemented yet.]
700
647
takes_args = ['branch_location?', 'to_location?']
701
648
takes_options = ['revision', # , 'basis']
717
663
raise BzrCommandError(
718
664
'bzr checkout --revision takes exactly 1 revision value')
719
665
if branch_location is None:
720
branch_location = osutils.getcwd()
666
branch_location = bzrlib.osutils.getcwd()
721
667
to_location = branch_location
722
668
source = Branch.open(branch_location)
723
669
if len(revision) == 1 and revision[0] is not None:
729
675
# if the source and to_location are the same,
730
676
# and there is no working tree,
731
677
# then reconstitute a branch
732
if (osutils.abspath(to_location) ==
733
osutils.abspath(branch_location)):
678
if (bzrlib.osutils.abspath(to_location) ==
679
bzrlib.osutils.abspath(branch_location)):
735
681
source.bzrdir.open_workingtree()
736
682
except errors.NoWorkingTree:
750
old_format = bzrdir.BzrDirFormat.get_default_format()
751
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
696
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
697
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
754
700
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
755
branch.BranchReferenceFormat().initialize(checkout, source)
701
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
757
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
703
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
758
704
to_location, force_new_tree=False)
759
705
checkout = checkout_branch.bzrdir
760
706
checkout_branch.bind(source)
778
724
def run(self, dir=u'.'):
779
from bzrlib.tree import find_renames
780
725
tree = WorkingTree.open_containing(dir)[0]
781
726
old_inv = tree.basis_tree().inventory
782
727
new_inv = tree.read_working_inventory()
783
renames = list(find_renames(old_inv, new_inv))
729
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
785
731
for old_name, new_name in renames:
786
self.outf.write("%s => %s\n" % (old_name, new_name))
732
print "%s => %s" % (old_name, new_name)
789
735
class cmd_update(Command):
802
748
tree = WorkingTree.open_containing(dir)[0]
803
749
tree.lock_write()
805
last_rev = tree.last_revision()
806
if last_rev == tree.branch.last_revision():
751
if tree.last_revision() == tree.branch.last_revision():
807
752
# may be up to date, check master too.
808
753
master = tree.branch.get_master_branch()
809
if master is None or last_rev == master.last_revision():
810
revno = tree.branch.revision_id_to_revno(last_rev)
811
note("Tree is up to date at revision %d." % (revno,))
754
if master is None or master.last_revision == tree.last_revision():
755
note("Tree is up to date.")
813
757
conflicts = tree.update()
814
revno = tree.branch.revision_id_to_revno(tree.last_revision())
815
note('Updated to revision %d.' % (revno,))
758
note('Updated to revision %d.' %
759
(tree.branch.revision_id_to_revno(tree.last_revision()),))
816
760
if conflicts != 0:
824
768
class cmd_info(Command):
825
"""Show information about a working tree, branch or repository.
827
This command will show all known locations and formats associated to the
828
tree, branch or repository. Statistical information is included with
831
Branches and working trees will also report any missing revisions.
833
takes_args = ['location?']
769
"""Show statistical information about a branch."""
770
takes_args = ['branch?']
834
771
takes_options = ['verbose']
837
def run(self, location=None, verbose=False):
838
from bzrlib.info import show_bzrdir_info
839
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
774
def run(self, branch=None, verbose=False):
776
bzrlib.info.show_bzrdir_info(bzrdir.BzrDir.open_containing(branch)[0],
843
780
class cmd_remove(Command):
846
783
This makes bzr stop tracking changes to a versioned file. It does
847
784
not delete the working copy.
849
You can specify one or more files, and/or --new. If you specify --new,
850
only 'added' files will be removed. If you specify both, then new files
851
in the specified directories will be removed. If the directories are
852
also new, they will also be removed.
854
takes_args = ['file*']
855
takes_options = ['verbose', Option('new', help='remove newly-added files')]
786
takes_args = ['file+']
787
takes_options = ['verbose']
857
encoding_type = 'replace'
859
def run(self, file_list, verbose=False, new=False):
790
def run(self, file_list, verbose=False):
860
791
tree, file_list = tree_files(file_list)
862
if file_list is None:
863
raise BzrCommandError('Specify one or more files to remove, or'
866
from bzrlib.delta import compare_trees
867
added = [compare_trees(tree.basis_tree(), tree,
868
specific_files=file_list).added]
869
file_list = sorted([f[0] for f in added[0]], reverse=True)
870
if len(file_list) == 0:
871
raise BzrCommandError('No matching files.')
872
tree.remove(file_list, verbose=verbose, to_file=self.outf)
792
tree.remove(file_list, verbose=verbose)
875
795
class cmd_file_id(Command):
891
809
raise BzrError("%r is not a versioned file" % filename)
893
self.outf.write(i + '\n')
896
814
class cmd_file_path(Command):
897
815
"""Print path of file_ids to a file or directory.
899
817
This prints one line for each directory down to the target,
900
starting at the branch root.
818
starting at the branch root."""
904
820
takes_args = ['filename']
907
822
def run(self, filename):
908
823
tree, relpath = WorkingTree.open_containing(filename)
937
852
def run(self, branch="."):
938
853
from bzrlib.reconcile import reconcile
939
dir = bzrdir.BzrDir.open(branch)
854
dir = bzrlib.bzrdir.BzrDir.open(branch)
943
858
class cmd_revision_history(Command):
944
"""Display the list of revision ids on a branch."""
945
takes_args = ['location?']
859
"""Display list of revision ids on this branch."""
950
def run(self, location="."):
951
branch = Branch.open_containing(location)[0]
952
for revid in branch.revision_history():
953
self.outf.write(revid)
954
self.outf.write('\n')
863
branch = WorkingTree.open_containing(u'.')[0].branch
864
for patchid in branch.revision_history():
957
868
class cmd_ancestry(Command):
958
869
"""List all revisions merged into this branch."""
959
takes_args = ['location?']
964
def run(self, location="."):
966
wt = WorkingTree.open_containing(location)[0]
967
except errors.NoWorkingTree:
968
b = Branch.open(location)
969
last_revision = b.last_revision()
972
last_revision = wt.last_revision()
974
revision_ids = b.repository.get_ancestry(last_revision)
975
assert revision_ids[0] == None
977
for revision_id in revision_ids:
978
self.outf.write(revision_id + '\n')
873
tree = WorkingTree.open_containing(u'.')[0]
875
# FIXME. should be tree.last_revision
876
for revision_id in b.repository.get_ancestry(b.last_revision()):
981
880
class cmd_init(Command):
984
883
Use this to create an empty branch, or before importing an
985
884
existing project.
987
If there is a repository in a parent directory of the location, then
988
the history of the branch will be stored in the repository. Otherwise
989
init creates a standalone branch which carries its own history in
992
If there is already a branch at the location but it has no working tree,
993
the tree can be populated with 'bzr checkout'.
995
886
Recipe for importing a tree of files:
1002
893
takes_args = ['location?']
1003
894
takes_options = [
1004
895
Option('format',
1005
help='Specify a format for this branch. Current'
1006
' formats are: default, knit, metaweave and'
1007
' weave. Default is knit; metaweave and'
1008
' weave are deprecated',
896
help='Create a specific format rather than the'
897
' current default format. Currently this '
898
' option only accepts "metadir"',
1009
899
type=get_format_type),
1011
901
def run(self, location=None, format=None):
1013
format = get_format_type('default')
902
from bzrlib.branch import Branch
1014
903
if location is None:
1022
911
if not os.path.exists(location):
1023
912
os.mkdir(location)
1025
existing_bzrdir = bzrdir.BzrDir.open(location)
914
existing = bzrdir.BzrDir.open(location)
1026
915
except NotBranchError:
1027
# really a NotBzrDir error...
1028
916
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1030
if existing_bzrdir.has_branch():
1031
if existing_bzrdir.has_workingtree():
1032
raise errors.AlreadyBranchError(location)
1034
raise errors.BranchExistsWithoutWorkingTree(location)
919
existing.open_branch()
920
except NotBranchError:
921
existing.create_branch()
922
existing.create_workingtree()
1036
existing_bzrdir.create_branch()
1037
existing_bzrdir.create_workingtree()
924
raise errors.AlreadyBranchError(location)
1040
927
class cmd_init_repository(Command):
1044
931
in the repository, not in the branch directory, if the branch format supports
1048
935
bzr init-repo repo
1050
bzr checkout --lightweight repo/trunk trunk-checkout
936
bzr init --format=metadir repo/trunk
1052
938
(add files here)
1054
940
takes_args = ["location"]
1055
941
takes_options = [Option('format',
1056
help='Specify a format for this repository.'
1057
' Current formats are: default, knit,'
1058
' metaweave and weave. Default is knit;'
1059
' metaweave and weave are deprecated',
942
help='Use a specific format rather than the'
943
' current default format. Currently this'
944
' option only accepts "metadir" and "knit"'
945
' WARNING: the knit format is currently unstable'
946
' and only for experimental use.',
1060
947
type=get_format_type),
1062
949
help='Allows branches in repository to have'
1063
950
' a working tree')]
1064
951
aliases = ["init-repo"]
1065
952
def run(self, location, format=None, trees=False):
953
from bzrlib.bzrdir import BzrDirMetaFormat1
1066
954
from bzrlib.transport import get_transport
1067
955
if format is None:
1068
format = get_format_type('default')
956
format = BzrDirMetaFormat1()
1069
957
transport = get_transport(location)
1070
958
if not transport.has('.'):
1071
959
transport.mkdir('')
1080
968
If files are listed, only the changes in those files are listed.
1081
969
Otherwise, all changes for the tree are listed.
1083
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1084
produces patches suitable for "patch -p1".
1090
bzr diff --diff-prefix old/:new/
1091
bzr diff bzr.mine bzr.dev
976
# TODO: Allow diff across branches.
1094
977
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1095
978
# or a graphical diff.
1097
980
# TODO: Python difflib is not exactly the same as unidiff; should
1098
981
# either fix it up or prefer to use an external diff.
983
# TODO: If a directory is given, diff everything under that.
1100
985
# TODO: Selected-file diff is inefficient and doesn't show you
1101
986
# deleted files.
1103
988
# TODO: This probably handles non-Unix newlines poorly.
1105
990
takes_args = ['file*']
1106
takes_options = ['revision', 'diff-options', 'prefix']
991
takes_options = ['revision', 'diff-options']
1107
992
aliases = ['di', 'dif']
1108
encoding_type = 'exact'
1110
994
@display_command
1111
def run(self, revision=None, file_list=None, diff_options=None,
995
def run(self, revision=None, file_list=None, diff_options=None):
1113
996
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1115
if (prefix is None) or (prefix == '0'):
1123
if not ':' in prefix:
1124
raise BzrError("--diff-prefix expects two values separated by a colon")
1125
old_label, new_label = prefix.split(":")
1128
998
tree1, file_list = internal_tree_files(file_list)
1144
1014
raise BzrCommandError("Can't specify -r with two branches")
1145
1015
if (len(revision) == 1) or (revision[1].spec is None):
1146
1016
return diff_cmd_helper(tree1, file_list, diff_options,
1148
old_label=old_label, new_label=new_label)
1149
1018
elif len(revision) == 2:
1150
1019
return diff_cmd_helper(tree1, file_list, diff_options,
1151
revision[0], revision[1],
1152
old_label=old_label, new_label=new_label)
1020
revision[0], revision[1])
1154
1022
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1156
1024
if tree2 is not None:
1157
1025
return show_diff_trees(tree1, tree2, sys.stdout,
1158
1026
specific_files=file_list,
1159
external_diff_options=diff_options,
1160
old_label=old_label, new_label=new_label)
1027
external_diff_options=diff_options)
1162
return diff_cmd_helper(tree1, file_list, diff_options,
1163
old_label=old_label, new_label=new_label)
1029
return diff_cmd_helper(tree1, file_list, diff_options)
1166
1032
class cmd_deleted(Command):
1172
1038
# directories with readdir, rather than stating each one. Same
1173
1039
# level of effort but possibly much less IO. (Or possibly not,
1174
1040
# if the directories are very large...)
1175
takes_options = ['show-ids']
1177
1041
@display_command
1178
1042
def run(self, show_ids=False):
1179
1043
tree = WorkingTree.open_containing(u'.')[0]
1180
1044
old = tree.basis_tree()
1181
1045
for path, ie in old.inventory.iter_entries():
1182
1046
if not tree.has_id(ie.file_id):
1183
self.outf.write(path)
1185
self.outf.write(' ')
1186
self.outf.write(ie.file_id)
1187
self.outf.write('\n')
1048
print '%-50s %s' % (path, ie.file_id)
1190
1053
class cmd_modified(Command):
1327
1191
if rev1 > rev2:
1328
1192
(rev2, rev1) = (rev1, rev2)
1194
mutter('encoding log as %r', bzrlib.user_encoding)
1196
# use 'replace' so that we don't abort if trying to write out
1197
# in e.g. the default C locale.
1198
outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1330
1200
if (log_format == None):
1331
default = b.get_config().log_format()
1332
log_format = get_log_format(long=long, short=short, line=line,
1201
default = bzrlib.config.BranchConfig(b).log_format()
1202
log_format = get_log_format(long=long, short=short, line=line, default=default)
1334
1204
lf = log_formatter(log_format,
1335
1205
show_ids=show_ids,
1337
1207
show_timezone=timezone)
1360
1230
class cmd_touching_revisions(Command):
1361
1231
"""Return revision-ids which affected a particular file.
1363
A more user-friendly interface is "bzr log FILE".
1233
A more user-friendly interface is "bzr log FILE"."""
1367
1235
takes_args = ["filename"]
1369
1236
@display_command
1370
1237
def run(self, filename):
1371
1238
tree, relpath = WorkingTree.open_containing(filename)
1372
1239
b = tree.branch
1373
1240
inv = tree.read_working_inventory()
1374
1241
file_id = inv.path2id(relpath)
1375
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
1376
self.outf.write("%6d %s\n" % (revno, what))
1242
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
1243
print "%6d %s" % (revno, what)
1379
1246
class cmd_ls(Command):
1424
1290
kindch = entry.kind_character()
1425
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1291
print '%-8s %s%s' % (fc, fp, kindch)
1427
self.outf.write(fp + '\0')
1293
sys.stdout.write(fp)
1294
sys.stdout.write('\0')
1430
self.outf.write(fp + '\n')
1433
1300
class cmd_unknowns(Command):
1434
1301
"""List unknown files."""
1435
1302
@display_command
1304
from bzrlib.osutils import quotefn
1437
1305
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1438
self.outf.write(osutils.quotefn(f) + '\n')
1441
1309
class cmd_ignore(Command):
1457
1325
bzr ignore '*.class'
1459
1327
# TODO: Complain if the filename is absolute
1460
takes_args = ['name_pattern?']
1462
Option('old-default-rules',
1463
help='Out the ignore rules bzr < 0.9 always used.')
1328
takes_args = ['name_pattern']
1466
def run(self, name_pattern=None, old_default_rules=None):
1330
def run(self, name_pattern):
1467
1331
from bzrlib.atomicfile import AtomicFile
1468
if old_default_rules is not None:
1469
# dump the rules and exit
1470
for pattern in bzrlib.DEFAULT_IGNORE:
1473
if name_pattern is None:
1474
raise BzrCommandError("ignore requires a NAME_PATTERN")
1475
1334
tree, relpath = WorkingTree.open_containing(u'.')
1476
1335
ifn = tree.abspath('.bzrignore')
1477
1337
if os.path.exists(ifn):
1478
1338
f = open(ifn, 'rt')
1564
1424
takes_args = ['dest']
1565
1425
takes_options = ['revision', 'format', 'root']
1566
1426
def run(self, dest, revision=None, format=None, root=None):
1567
1428
from bzrlib.export import export
1568
1429
tree = WorkingTree.open_containing(u'.')[0]
1569
1430
b = tree.branch
1675
1537
# TODO: if the commit *does* happen to fail, then save the commit
1676
1538
# message to a temporary file where it can be recovered
1677
1539
tree, selected_list = tree_files(selected_list)
1678
if selected_list == ['']:
1679
# workaround - commit of root of tree should be exactly the same
1680
# as just default commit in that tree, and succeed even though
1681
# selected-file merge commit is not done yet
1684
1540
if local and not tree.branch.get_bound_location():
1685
1541
raise errors.LocalRequiresBoundBranch()
1686
1542
if message is None and not file:
1710
1567
except PointlessCommit:
1711
1568
# FIXME: This should really happen before the file is read in;
1712
1569
# perhaps prepare the commit; get the message; then actually commit
1713
raise BzrCommandError("no changes to commit."
1714
" use --unchanged to commit anyhow")
1570
raise BzrCommandError("no changes to commit",
1571
["use --unchanged to commit anyhow"])
1715
1572
except ConflictsInTree:
1716
1573
raise BzrCommandError("Conflicts detected in working tree. "
1717
1574
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1772
1629
takes_args = ['url?']
1773
1630
takes_options = [
1774
1631
Option('format',
1775
help='Upgrade to a specific format. Current formats'
1776
' are: default, knit, metaweave and weave.'
1777
' Default is knit; metaweave and weave are'
1632
help='Upgrade to a specific format rather than the'
1633
' current default format. Currently this'
1634
' option only accepts "metadir" and "knit".'
1635
' WARNING: the knit format is currently'
1636
' unstable and only for experimental use.',
1779
1637
type=get_format_type),
1783
1641
def run(self, url='.', format=None):
1784
1642
from bzrlib.upgrade import upgrade
1786
format = get_format_type('default')
1787
1643
upgrade(url, format)
1790
1646
class cmd_whoami(Command):
1791
"""Show or set bzr user id.
1795
bzr whoami 'Frank Chu <fchu@example.com>'
1797
takes_options = [ Option('email',
1798
help='display email address only'),
1800
help='set identity for the current branch instead of '
1803
takes_args = ['name?']
1804
encoding_type = 'replace'
1647
"""Show bzr user id."""
1648
takes_options = ['email']
1806
1650
@display_command
1807
def run(self, email=False, branch=False, name=None):
1809
# use branch if we're inside one; otherwise global config
1811
c = Branch.open_containing('.')[0].get_config()
1812
except NotBranchError:
1813
c = config.GlobalConfig()
1815
self.outf.write(c.user_email() + '\n')
1817
self.outf.write(c.username() + '\n')
1820
# use global config unless --branch given
1822
c = Branch.open_containing('.')[0].get_config()
1651
def run(self, email=False):
1653
b = WorkingTree.open_containing(u'.')[0].branch
1654
config = bzrlib.config.BranchConfig(b)
1655
except NotBranchError:
1656
config = bzrlib.config.GlobalConfig()
1659
print config.user_email()
1824
c = config.GlobalConfig()
1825
c.set_user_option('email', name)
1661
print config.username()
1828
1664
class cmd_nick(Command):
1893
1729
help='Use a different transport by default '
1894
1730
'throughout the test suite.',
1895
1731
type=get_transport_type),
1896
Option('benchmark', help='run the bzr bencharks.'),
1897
Option('lsprof-timed',
1898
help='generate lsprof output for benchmarked'
1899
' sections of code.'),
1902
def run(self, testspecs_list=None, verbose=None, one=False,
1903
keep_output=False, transport=None, benchmark=None,
1734
def run(self, testspecs_list=None, verbose=False, one=False,
1735
keep_output=False, transport=None):
1905
1736
import bzrlib.ui
1906
1737
from bzrlib.tests import selftest
1907
import bzrlib.benchmarks as benchmarks
1908
1738
# we don't want progress meters from the tests to go to the
1909
1739
# real output; and we don't want log messages cluttering up
1910
1740
# the real logs.
1911
save_ui = ui.ui_factory
1912
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1913
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1915
info('running tests...')
1741
save_ui = bzrlib.ui.ui_factory
1742
bzrlib.trace.info('running tests...')
1917
ui.ui_factory = ui.SilentUIFactory()
1744
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1918
1745
if testspecs_list is not None:
1919
1746
pattern = '|'.join(testspecs_list)
1923
test_suite_factory = benchmarks.test_suite
1927
test_suite_factory = None
1930
1749
result = selftest(verbose=verbose,
1931
1750
pattern=pattern,
1932
1751
stop_on_failure=one,
1933
1752
keep_output=keep_output,
1934
transport=transport,
1935
test_suite_factory=test_suite_factory,
1936
lsprof_timed=lsprof_timed)
1753
transport=transport)
1938
info('tests passed')
1755
bzrlib.trace.info('tests passed')
1940
info('tests failed')
1757
bzrlib.trace.info('tests failed')
1941
1758
return int(not result)
1943
ui.ui_factory = save_ui
1760
bzrlib.ui.ui_factory = save_ui
1946
1763
def _get_bzr_branch():
1947
1764
"""If bzr is run from a branch, return Branch or None"""
1765
import bzrlib.errors
1766
from bzrlib.branch import Branch
1767
from bzrlib.osutils import abspath
1948
1768
from os.path import dirname
1951
branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1771
branch = Branch.open(dirname(abspath(dirname(__file__))))
1953
except errors.BzrError:
1773
except bzrlib.errors.BzrError:
1957
1777
def show_version():
1959
1778
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1960
1779
# is bzrlib itself in a branch?
1961
1780
branch = _get_bzr_branch()
1966
1785
print " nick: %s" % (branch.nick,)
1968
1787
print " revid: %s" % (rh[-1],)
1969
print "Using python interpreter:", sys.executable
1971
print "Using python standard library:", os.path.dirname(site.__file__)
1972
print "Using bzrlib:",
1973
if len(bzrlib.__path__) > 1:
1974
# print repr, which is a good enough way of making it clear it's
1975
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1976
print repr(bzrlib.__path__)
1978
print bzrlib.__path__[0]
1981
1788
print bzrlib.__copyright__
1982
print "http://bazaar-vcs.org/"
1789
print "http://bazaar-ng.org/"
1984
1791
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
1985
1792
print "you may use, modify and redistribute it under the terms of the GNU"
2027
1834
base_rev_id = common_ancestor(last1, last2, source)
2029
1836
print 'merge base is revision %s' % base_rev_id
1840
if base_revno is None:
1841
raise bzrlib.errors.UnrelatedBranches()
1843
print ' r%-6d in %s' % (base_revno, branch)
1845
other_revno = branch2.revision_id_to_revno(base_revid)
1847
print ' r%-6d in %s' % (other_revno, other)
2032
1851
class cmd_merge(Command):
2033
1852
"""Perform a three-way merge.
2035
The branch is the branch you will merge from. By default, it will merge
2036
the latest revision. If you specify a revision, that revision will be
2037
merged. If you specify two revisions, the first will be used as a BASE,
2038
and the second one as OTHER. Revision numbers are always relative to the
1854
The branch is the branch you will merge from. By default, it will
1855
merge the latest revision. If you specify a revision, that
1856
revision will be merged. If you specify two revisions, the first
1857
will be used as a BASE, and the second one as OTHER. Revision
1858
numbers are always relative to the specified branch.
2041
1860
By default, bzr will try to merge in all new work from the other
2042
1861
branch, automatically determining an appropriate base. If this
2068
1886
merge refuses to run if there are any uncommitted changes, unless
2069
1887
--force is given.
2071
The following merge types are available:
2073
1889
takes_args = ['branch?']
2074
1890
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2075
1891
Option('show-base', help="Show base revision text in "
2079
from merge import merge_type_help
2080
from inspect import getdoc
2081
return getdoc(self) + '\n' + merge_type_help()
2083
1894
def run(self, branch=None, revision=None, force=False, merge_type=None,
2084
1895
show_base=False, reprocess=False, remember=False):
2085
1896
if merge_type is None:
2086
1897
merge_type = Merge3Merger
2088
1899
tree = WorkingTree.open_containing(u'.')[0]
2090
if branch is not None:
2092
reader = bundle.read_bundle_from_url(branch)
2094
pass # Continue on considering this url a Branch
1900
stored_loc = tree.branch.get_parent()
1902
if stored_loc is None:
1903
raise BzrCommandError("No merge branch known or specified.")
2096
conflicts = merge_bundle(reader, tree, not force, merge_type,
2097
reprocess, show_base)
1905
print "Using saved branch: %s" % stored_loc
2103
branch = self._get_remembered_parent(tree, branch, 'Merging from')
1908
if tree.branch.get_parent() is None or remember:
1909
tree.branch.set_parent(branch)
2105
1911
if revision is None or len(revision) < 1:
2106
1912
base = [None, None]
2117
1923
if None in revision:
2118
1924
raise BzrCommandError(
2119
1925
"Merge doesn't permit that revision specifier.")
2120
other_branch, path = Branch.open_containing(branch)
2122
base = [branch, revision[0].in_history(other_branch).revno]
2123
other = [branch, revision[1].in_history(other_branch).revno]
2125
if tree.branch.get_parent() is None or remember:
2126
tree.branch.set_parent(other_branch.base)
1926
b, path = Branch.open_containing(branch)
1928
base = [branch, revision[0].in_history(b).revno]
1929
other = [branch, revision[1].in_history(b).revno]
2129
1931
interesting_files = [path]
2131
1933
interesting_files = None
2132
pb = ui.ui_factory.nested_progress_bar()
1934
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2135
1937
conflict_count = merge(other, base, check_clean=(not force),
2136
merge_type=merge_type,
1938
merge_type=merge_type,
2137
1939
reprocess=reprocess,
2138
show_base=show_base,
1940
show_base=show_base,
2139
1941
pb=pb, file_list=interesting_files)
2152
1954
"and (if you want) report this to the bzr developers\n")
2155
# TODO: move up to common parent; this isn't merge-specific anymore.
2156
def _get_remembered_parent(self, tree, supplied_location, verb_string):
2157
"""Use tree.branch's parent if none was supplied.
2159
Report if the remembered location was used.
2161
if supplied_location is not None:
2162
return supplied_location
2163
stored_location = tree.branch.get_parent()
2164
mutter("%s", stored_location)
2165
if stored_location is None:
2166
raise BzrCommandError("No location specified or remembered")
2167
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2168
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2169
return stored_location
2172
1958
class cmd_remerge(Command):
2173
1959
"""Redo a merge.
2175
Use this if you want to try a different merge technique while resolving
2176
conflicts. Some merge techniques are better than others, and remerge
2177
lets you try different ones on different files.
2179
The options for remerge have the same meaning and defaults as the ones for
2180
merge. The difference is that remerge can (only) be run when there is a
2181
pending merge, and it lets you specify particular files.
2184
$ bzr remerge --show-base
2185
Re-do the merge of all conflicted files, and show the base text in
2186
conflict regions, in addition to the usual THIS and OTHER texts.
2188
$ bzr remerge --merge-type weave --reprocess foobar
2189
Re-do the merge of "foobar", using the weave merge algorithm, with
2190
additional processing to reduce the size of conflict regions.
2192
The following merge types are available:"""
2193
1961
takes_args = ['file*']
2194
1962
takes_options = ['merge-type', 'reprocess',
2195
1963
Option('show-base', help="Show base revision text in "
2199
from merge import merge_type_help
2200
from inspect import getdoc
2201
return getdoc(self) + '\n' + merge_type_help()
2203
1966
def run(self, file_list=None, merge_type=None, show_base=False,
2204
1967
reprocess=False):
2205
1968
from bzrlib.merge import merge_inner, transform_tree
2211
1974
pending_merges = tree.pending_merges()
2212
1975
if len(pending_merges) != 1:
2213
1976
raise BzrCommandError("Sorry, remerge only works after normal"
2214
" merges. Not cherrypicking or"
1977
+ " merges. Not cherrypicking or"
2216
1979
repository = tree.branch.repository
2217
1980
base_revision = common_ancestor(tree.branch.last_revision(),
2218
1981
pending_merges[0], repository)
2219
1982
base_tree = repository.revision_tree(base_revision)
2220
1983
other_tree = repository.revision_tree(pending_merges[0])
2221
1984
interesting_ids = None
2223
conflicts = tree.conflicts()
2224
1985
if file_list is not None:
2225
1986
interesting_ids = set()
2226
1987
for filename in file_list:
2234
1995
for name, ie in tree.inventory.iter_entries(file_id):
2235
1996
interesting_ids.add(ie.file_id)
2236
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2237
1997
transform_tree(tree, tree.basis_tree(), interesting_ids)
2238
tree.set_conflicts(ConflictList(new_conflicts))
2239
1998
if file_list is None:
2240
1999
restore_files = list(tree.iter_conflicts())
2245
2004
restore(tree.abspath(filename))
2246
2005
except NotConflicted:
2248
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2250
interesting_ids=interesting_ids,
2251
other_rev_id=pending_merges[0],
2252
merge_type=merge_type,
2253
show_base=show_base,
2254
reprocess=reprocess)
2007
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2009
interesting_ids = interesting_ids,
2010
other_rev_id=pending_merges[0],
2011
merge_type=merge_type,
2012
show_base=show_base,
2013
reprocess=reprocess)
2257
2016
if conflicts > 0:
2340
2099
takes_args = ['from_branch', 'to_branch']
2341
2100
def run(self, from_branch, to_branch):
2342
2101
from bzrlib.fetch import Fetcher
2102
from bzrlib.branch import Branch
2343
2103
from_b = Branch.open(from_branch)
2344
2104
to_b = Branch.open(to_branch)
2345
2105
Fetcher(to_b, from_b)
2365
encoding_type = 'replace'
2368
2126
def run(self, other_branch=None, reverse=False, mine_only=False,
2369
2127
theirs_only=False, log_format=None, long=False, short=False, line=False,
2370
2128
show_ids=False, verbose=False):
2371
2129
from bzrlib.missing import find_unmerged, iter_log_data
2372
2130
from bzrlib.log import log_formatter
2373
local_branch = Branch.open_containing(u".")[0]
2131
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
2374
2132
parent = local_branch.get_parent()
2375
2133
if other_branch is None:
2376
2134
other_branch = parent
2377
2135
if other_branch is None:
2378
2136
raise BzrCommandError("No missing location known or specified.")
2379
2137
print "Using last location: " + local_branch.get_parent()
2380
remote_branch = Branch.open(other_branch)
2138
remote_branch = bzrlib.branch.Branch.open(other_branch)
2139
local_branch.lock_write()
2381
2140
if remote_branch.base == local_branch.base:
2382
2141
remote_branch = local_branch
2383
local_branch.lock_read()
2385
2143
remote_branch.lock_read()
2387
2145
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2388
2146
if (log_format == None):
2389
default = local_branch.get_config().log_format()
2390
log_format = get_log_format(long=long, short=short,
2391
line=line, default=default)
2392
lf = log_formatter(log_format,
2147
default = bzrlib.config.BranchConfig(local_branch).log_format()
2148
log_format = get_log_format(long=long, short=short, line=line, default=default)
2149
lf = log_formatter(log_format, sys.stdout,
2394
2150
show_ids=show_ids,
2395
2151
show_timezone='original')
2396
2152
if reverse is False:
2416
2172
print "Branches are up to date."
2418
2174
status_code = 1
2420
remote_branch.unlock()
2422
local_branch.unlock()
2423
if not status_code and parent is None and other_branch is not None:
2424
local_branch.lock_write()
2426
# handle race conditions - a parent might be set while we run.
2427
if local_branch.get_parent() is None:
2428
local_branch.set_parent(remote_branch.base)
2175
if parent is None and other_branch is not None:
2176
local_branch.set_parent(other_branch)
2430
2179
local_branch.unlock()
2181
remote_branch.unlock()
2434
2184
class cmd_plugins(Command):
2454
2204
class cmd_testament(Command):
2455
2205
"""Show testament (signing-form) of a revision."""
2456
takes_options = ['revision', 'long',
2457
Option('strict', help='Produce a strict-format'
2206
takes_options = ['revision', 'long']
2459
2207
takes_args = ['branch?']
2460
2208
@display_command
2461
def run(self, branch=u'.', revision=None, long=False, strict=False):
2462
from bzrlib.testament import Testament, StrictTestament
2464
testament_class = StrictTestament
2466
testament_class = Testament
2209
def run(self, branch=u'.', revision=None, long=False):
2210
from bzrlib.testament import Testament
2467
2211
b = WorkingTree.open_containing(branch)[0].branch
2490
2234
shown only at the top, unless the --all option is given.
2492
2236
# TODO: annotate directories; showing when each file was last changed
2237
# TODO: annotate a previous version of a file
2493
2238
# TODO: if the working copy is modified, show annotations on that
2494
2239
# with new uncommitted lines marked
2495
aliases = ['ann', 'blame', 'praise']
2240
aliases = ['blame', 'praise']
2496
2241
takes_args = ['filename']
2497
2242
takes_options = [Option('all', help='show annotations on all lines'),
2498
2243
Option('long', help='show date in annotations'),
2502
2246
@display_command
2503
def run(self, filename, all=False, long=False, revision=None):
2247
def run(self, filename, all=False, long=False):
2504
2248
from bzrlib.annotate import annotate_file
2505
2249
tree, relpath = WorkingTree.open_containing(filename)
2506
2250
branch = tree.branch
2507
2251
branch.lock_read()
2509
if revision is None:
2510
revision_id = branch.last_revision()
2511
elif len(revision) != 1:
2512
raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2514
revision_id = revision[0].in_history(branch).rev_id
2515
2253
file_id = tree.inventory.path2id(relpath)
2516
tree = branch.repository.revision_tree(revision_id)
2254
tree = branch.repository.revision_tree(branch.last_revision())
2517
2255
file_version = tree.inventory[file_id].revision
2518
2256
annotate_file(branch, file_version, file_id, long, all, sys.stdout)
2529
2267
takes_options = ['revision']
2531
2269
def run(self, revision_id_list=None, revision=None):
2270
import bzrlib.config as config
2532
2271
import bzrlib.gpg as gpg
2533
2272
if revision_id_list is not None and revision is not None:
2534
2273
raise BzrCommandError('You can only supply one of revision_id or --revision')
2535
2274
if revision_id_list is None and revision is None:
2536
2275
raise BzrCommandError('You must supply either --revision or a revision_id')
2537
2276
b = WorkingTree.open_containing(u'.')[0].branch
2538
gpg_strategy = gpg.GPGStrategy(b.get_config())
2277
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
2539
2278
if revision_id_list is not None:
2540
2279
for revision_id in revision_id_list:
2541
2280
b.repository.sign_revision(revision_id, gpg_strategy)
2596
2334
raise BzrCommandError('Local branch is not bound')
2599
class cmd_uncommit(Command):
2337
class cmd_uncommit(bzrlib.commands.Command):
2600
2338
"""Remove the last committed revision.
2340
By supplying the --all flag, it will not only remove the entry
2341
from revision_history, but also remove all of the entries in the
2602
2344
--verbose will print out what is being removed.
2603
2345
--dry-run will go through all the motions, but not actually
2604
2346
remove anything.
2606
In the future, uncommit will create a revision bundle, which can then
2348
In the future, uncommit will create a changeset, which can then
2610
2352
# TODO: jam 20060108 Add an option to allow uncommit to remove
2611
# unreferenced information in 'branch-as-repository' branches.
2353
# unreferenced information in 'branch-as-repostory' branches.
2612
2354
# TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
2613
2355
# information in shared branches as well.
2614
2356
takes_options = ['verbose', 'revision',
2620
2362
def run(self, location=None,
2621
2363
dry_run=False, verbose=False,
2622
2364
revision=None, force=False):
2365
from bzrlib.branch import Branch
2623
2366
from bzrlib.log import log_formatter
2625
2368
from bzrlib.uncommit import uncommit
2669
2412
CAUTION: Locks should only be broken when you are sure that the process
2670
2413
holding the lock has been stopped.
2672
You can get information on what locks are open via the 'bzr info' command.
2677
takes_args = ['location?']
2679
def run(self, location=None, show=False):
2680
if location is None:
2682
control, relpath = bzrdir.BzrDir.open_containing(location)
2684
control.break_lock()
2685
except NotImplementedError:
2418
takes_args = ['location']
2419
takes_options = [Option('show',
2420
help="just show information on the lock, " \
2423
def run(self, location, show=False):
2424
raise NotImplementedError("sorry, break-lock is not complete yet; "
2425
"you can remove the 'held' directory manually to break the lock")
2690
2428
# command-line interpretation helper for merge-related commands
2727
2465
if show_base and not merge_type is Merge3Merger:
2728
2466
raise BzrCommandError("Show-base is not supported for this merge"
2729
2467
" type. %s" % merge_type)
2730
if reprocess and not merge_type.supports_reprocess:
2731
raise BzrCommandError("Conflict reduction is not supported for merge"
2732
" type %s." % merge_type)
2468
if reprocess and not merge_type is Merge3Merger:
2469
raise BzrCommandError("Reprocess is not supported for this merge"
2470
" type. %s" % merge_type)
2733
2471
if reprocess and show_base:
2734
raise BzrCommandError("Cannot do conflict reduction and show base.")
2472
raise BzrCommandError("Cannot reprocess and show base.")
2736
2474
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2737
2475
merger.pp = ProgressPhase("Merge phase", 5, pb)
2762
2500
# aliases. ideally we would avoid loading the implementation until the
2763
2501
# details were needed.
2764
2502
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2765
from bzrlib.bundle.commands import cmd_bundle_revisions
2766
2503
from bzrlib.sign_my_commits import cmd_sign_my_commits
2767
2504
from bzrlib.weave_commands import cmd_weave_list, cmd_weave_join, \
2768
2505
cmd_weave_plan_merge, cmd_weave_merge_text