1
1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
from shutil import rmtree
28
from bzrlib.branch import Branch
29
import bzrlib.bzrdir as bzrdir
30
from bzrlib.bundle.read_bundle import BundleReader
31
from bzrlib.bundle.apply_bundle import merge_bundle
41
from bzrlib.branch import Branch, BranchReferenceFormat
42
from bzrlib.bundle import read_bundle_from_url
43
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
44
from bzrlib.conflicts import ConflictList
32
45
from bzrlib.commands import Command, display_command
33
import bzrlib.errors as errors
34
46
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
35
47
NotBranchError, DivergedBranches, NotConflicted,
36
48
NoSuchFile, NoWorkingTree, FileInWrongBranch,
37
49
NotVersionedError, NotABundle)
38
from bzrlib.log import show_one_log
39
50
from bzrlib.merge import Merge3Merger
40
51
from bzrlib.option import Option
42
52
from bzrlib.progress import DummyProgress, ProgressPhase
43
53
from bzrlib.revision import common_ancestor
44
54
from bzrlib.revisionspec import RevisionSpec
46
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
55
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
47
56
from bzrlib.transport.local import LocalTransport
49
import bzrlib.urlutils as urlutils
50
57
from bzrlib.workingtree import WorkingTree
94
101
return bzrdir.BzrDirMetaFormat1()
95
102
if typestring == "metaweave":
96
103
format = bzrdir.BzrDirMetaFormat1()
97
format.repository_format = bzrlib.repository.RepositoryFormat7()
104
format.repository_format = repository.RepositoryFormat7()
99
106
if typestring == "knit":
100
107
format = bzrdir.BzrDirMetaFormat1()
101
format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
108
format.repository_format = repository.RepositoryFormatKnit1()
110
if typestring == "experimental-knit2":
111
format = bzrdir.BzrDirMetaFormat1()
112
format.repository_format = repository.RepositoryFormatKnit2()
103
114
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
104
115
"metaweave and weave" % typestring
154
161
# TODO: --no-recurse, --recurse options
156
163
takes_args = ['file*']
157
takes_options = ['all', 'show-ids', 'revision']
164
takes_options = ['show-ids', 'revision']
158
165
aliases = ['st', 'stat']
160
167
encoding_type = 'replace'
163
def run(self, all=False, show_ids=False, file_list=None, revision=None):
170
def run(self, show_ids=False, file_list=None, revision=None):
164
171
from bzrlib.status import show_tree_status
166
173
tree, file_list = tree_files(file_list)
168
show_tree_status(tree, show_unchanged=all, show_ids=show_ids,
175
show_tree_status(tree, show_ids=show_ids,
169
176
specific_files=file_list, revision=revision,
170
177
to_file=self.outf)
272
279
--dry-run will show which files would be added, but not actually
282
--file-ids-from will try to use the file ids from the supplied path.
283
It looks up ids trying to find a matching parent directory with the
284
same filename, and then by pure path.
275
286
takes_args = ['file*']
276
takes_options = ['no-recurse', 'dry-run', 'verbose']
287
takes_options = ['no-recurse', 'dry-run', 'verbose',
288
Option('file-ids-from', type=unicode,
289
help='Lookup file ids from here')]
277
290
encoding_type = 'replace'
279
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
292
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
280
294
import bzrlib.add
282
action = bzrlib.add.AddAction(to_file=self.outf,
283
should_print=(not is_quiet()))
285
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
296
if file_ids_from is not None:
298
base_tree, base_path = WorkingTree.open_containing(
300
except errors.NoWorkingTree:
301
base_branch, base_path = branch.Branch.open_containing(
303
base_tree = base_branch.basis_tree()
305
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
306
to_file=self.outf, should_print=(not is_quiet()))
308
action = bzrlib.add.AddAction(to_file=self.outf,
309
should_print=(not is_quiet()))
311
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
286
312
action=action, save=not dry_run)
287
313
if len(ignored) > 0:
410
439
from one into the other. Once one branch has merged, the other should
411
440
be able to pull it again.
413
If branches have diverged, you can use 'bzr merge' to pull the text changes
414
from one into the other. Once one branch has merged, the other should
415
be able to pull it again.
417
442
If you want to forget your local changes and just update your branch to
418
443
match the remote one, use pull --overwrite.
420
445
If there is no default location set, the first pull will set it. After
421
446
that, you can omit the location to use the default. To change the
422
default, use --remember.
447
default, use --remember. The value will only be saved if the remote
448
location can be accessed.
425
451
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
444
478
self.outf.write("Using saved location: %s\n" % display_url)
445
479
location = stored_loc
447
branch_from = Branch.open(location)
449
if branch_to.get_parent() is None or remember:
450
branch_to.set_parent(branch_from.base)
482
if reader is not None:
483
install_bundle(branch_to.repository, reader)
484
branch_from = branch_to
486
branch_from = Branch.open(location)
488
if branch_to.get_parent() is None or remember:
489
branch_to.set_parent(branch_from.base)
452
492
if revision is None:
493
if reader is not None:
494
rev_id = reader.target
454
495
elif len(revision) == 1:
455
496
rev_id = revision[0].in_history(branch_from).rev_id
495
536
If there is no default push location set, the first push will set it.
496
537
After that, you can omit the location to use the default. To change the
497
default, use --remember.
538
default, use --remember. The value will only be saved if the remote
539
location can be accessed.
500
542
takes_options = ['remember', 'overwrite', 'verbose',
519
560
display_url = urlutils.unescape_for_display(stored_loc,
520
561
self.outf.encoding)
521
self.outf.write("Using saved location: %s" % display_url)
562
self.outf.write("Using saved location: %s\n" % display_url)
522
563
location = stored_loc
524
transport = get_transport(location)
525
location_url = transport.base
526
if br_from.get_push_location() is None or remember:
527
br_from.set_push_location(location_url)
565
to_transport = transport.get_transport(location)
566
location_url = to_transport.base
531
dir_to = bzrlib.bzrdir.BzrDir.open(location_url)
570
dir_to = bzrdir.BzrDir.open(location_url)
532
571
br_to = dir_to.open_branch()
533
572
except NotBranchError:
534
573
# create a branch.
535
transport = transport.clone('..')
574
to_transport = to_transport.clone('..')
536
575
if not create_prefix:
538
relurl = transport.relpath(location_url)
577
relurl = to_transport.relpath(location_url)
539
578
mutter('creating directory %s => %s', location_url, relurl)
540
transport.mkdir(relurl)
579
to_transport.mkdir(relurl)
541
580
except NoSuchFile:
542
581
raise BzrCommandError("Parent directory of %s "
543
582
"does not exist." % location)
545
current = transport.base
546
needed = [(transport, transport.relpath(location_url))]
584
current = to_transport.base
585
needed = [(to_transport, to_transport.relpath(location_url))]
549
transport, relpath = needed[-1]
550
transport.mkdir(relpath)
588
to_transport, relpath = needed[-1]
589
to_transport.mkdir(relpath)
552
591
except NoSuchFile:
553
new_transport = transport.clone('..')
592
new_transport = to_transport.clone('..')
554
593
needed.append((new_transport,
555
new_transport.relpath(transport.base)))
556
if new_transport.base == transport.base:
594
new_transport.relpath(to_transport.base)))
595
if new_transport.base == to_transport.base:
557
596
raise BzrCommandError("Could not create "
559
598
dir_to = br_from.bzrdir.clone(location_url,
560
599
revision_id=br_from.last_revision())
561
600
br_to = dir_to.open_branch()
562
601
count = len(br_to.revision_history())
602
# We successfully created the target, remember it
603
if br_from.get_push_location() is None or remember:
604
br_from.set_push_location(br_to.base)
606
# We were able to connect to the remote location, so remember it
607
# we don't need to successfully push because of possible divergence.
608
if br_from.get_push_location() is None or remember:
609
br_from.set_push_location(br_to.base)
564
610
old_rh = br_to.revision_history()
640
684
name = os.path.basename(to_location) + '\n'
642
to_transport = get_transport(to_location)
686
to_transport = transport.get_transport(to_location)
644
688
to_transport.mkdir('.')
645
except bzrlib.errors.FileExists:
689
except errors.FileExists:
646
690
raise BzrCommandError('Target directory "%s" already'
647
691
' exists.' % to_location)
648
except bzrlib.errors.NoSuchFile:
692
except errors.NoSuchFile:
649
693
raise BzrCommandError('Parent of "%s" does not exist.' %
653
697
dir = br_from.bzrdir.sprout(to_transport.base,
654
698
revision_id, basis_dir)
655
699
branch = dir.open_branch()
656
except bzrlib.errors.NoSuchRevision:
700
except errors.NoSuchRevision:
657
701
to_transport.delete_tree('.')
658
702
msg = "The branch %s has no revision %s." % (from_location, revision[0])
659
703
raise BzrCommandError(msg)
660
except bzrlib.errors.UnlistableBranch:
704
except errors.UnlistableBranch:
705
osutils.rmtree(to_location)
662
706
msg = "The branch %s cannot be used as a --basis" % (basis,)
663
707
raise BzrCommandError(msg)
719
764
# if the source and to_location are the same,
720
765
# and there is no working tree,
721
766
# then reconstitute a branch
722
if (bzrlib.osutils.abspath(to_location) ==
723
bzrlib.osutils.abspath(branch_location)):
767
if (osutils.abspath(to_location) ==
768
osutils.abspath(branch_location)):
725
770
source.bzrdir.open_workingtree()
726
771
except errors.NoWorkingTree:
740
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
741
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
785
old_format = bzrdir.BzrDirFormat.get_default_format()
786
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
744
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
745
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
747
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
748
to_location, force_new_tree=False)
749
checkout = checkout_branch.bzrdir
750
checkout_branch.bind(source)
751
if revision_id is not None:
752
rh = checkout_branch.revision_history()
753
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
754
checkout.create_workingtree(revision_id)
788
source.create_checkout(to_location, revision_id, lightweight)
756
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
790
bzrdir.BzrDirFormat.set_default_format(old_format)
759
793
class cmd_renames(Command):
768
802
def run(self, dir=u'.'):
803
from bzrlib.tree import find_renames
769
804
tree = WorkingTree.open_containing(dir)[0]
770
805
old_inv = tree.basis_tree().inventory
771
806
new_inv = tree.read_working_inventory()
773
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
807
renames = list(find_renames(old_inv, new_inv))
775
809
for old_name, new_name in renames:
776
810
self.outf.write("%s => %s\n" % (old_name, new_name))
787
821
'bzr revert' instead of 'bzr commit' after the update.
789
823
takes_args = ['dir?']
791
826
def run(self, dir='.'):
792
827
tree = WorkingTree.open_containing(dir)[0]
793
828
tree.lock_write()
795
if tree.last_revision() == tree.branch.last_revision():
830
existing_pending_merges = tree.get_parent_ids()[1:]
831
last_rev = tree.last_revision()
832
if last_rev == tree.branch.last_revision():
796
833
# may be up to date, check master too.
797
834
master = tree.branch.get_master_branch()
798
if master is None or master.last_revision == tree.last_revision():
799
note("Tree is up to date.")
835
if master is None or last_rev == master.last_revision():
836
revno = tree.branch.revision_id_to_revno(last_rev)
837
note("Tree is up to date at revision %d." % (revno,))
801
839
conflicts = tree.update()
802
note('Updated to revision %d.' %
803
(tree.branch.revision_id_to_revno(tree.last_revision()),))
840
revno = tree.branch.revision_id_to_revno(tree.last_revision())
841
note('Updated to revision %d.' % (revno,))
842
if tree.get_parent_ids()[1:] != existing_pending_merges:
843
note('Your local commits will now show as pending merges with '
844
"'bzr status', and can be committed with 'bzr commit'.")
804
845
if conflicts != 0:
851
892
raise BzrCommandError('Specify one or more files to remove, or'
854
from bzrlib.delta import compare_trees
855
added = [compare_trees(tree.basis_tree(), tree,
856
specific_files=file_list).added]
857
file_list = sorted([f[0] for f in added[0]], reverse=True)
895
added = tree.changes_from(tree.basis_tree(),
896
specific_files=file_list).added
897
file_list = sorted([f[0] for f in added], reverse=True)
858
898
if len(file_list) == 0:
859
899
raise BzrCommandError('No matching files.')
860
900
tree.remove(file_list, verbose=verbose, to_file=self.outf)
925
965
def run(self, branch="."):
926
966
from bzrlib.reconcile import reconcile
927
dir = bzrlib.bzrdir.BzrDir.open(branch)
967
dir = bzrdir.BzrDir.open(branch)
931
971
class cmd_revision_history(Command):
932
"""Display list of revision ids on this branch."""
972
"""Display the list of revision ids on a branch."""
973
takes_args = ['location?']
937
branch = WorkingTree.open_containing(u'.')[0].branch
938
for patchid in branch.revision_history():
939
self.outf.write(patchid)
978
def run(self, location="."):
979
branch = Branch.open_containing(location)[0]
980
for revid in branch.revision_history():
981
self.outf.write(revid)
940
982
self.outf.write('\n')
943
985
class cmd_ancestry(Command):
944
986
"""List all revisions merged into this branch."""
987
takes_args = ['location?']
949
tree = WorkingTree.open_containing(u'.')[0]
951
# FIXME. should be tree.last_revision
952
revision_ids = b.repository.get_ancestry(b.last_revision())
953
assert revision_ids[0] == None
992
def run(self, location="."):
994
wt = WorkingTree.open_containing(location)[0]
995
except errors.NoWorkingTree:
996
b = Branch.open(location)
997
last_revision = b.last_revision()
1000
last_revision = wt.last_revision()
1002
revision_ids = b.repository.get_ancestry(last_revision)
1003
assert revision_ids[0] is None
954
1004
revision_ids.pop(0)
955
1005
for revision_id in revision_ids:
956
1006
self.outf.write(revision_id + '\n')
987
1037
type=get_format_type),
989
1039
def run(self, location=None, format=None):
990
from bzrlib.branch import Branch
991
1040
if format is None:
992
1041
format = get_format_type('default')
993
1042
if location is None:
996
# The path has to exist to initialize a
997
# branch inside of it.
998
# Just using os.mkdir, since I don't
999
# believe that we want to create a bunch of
1000
# locations if the user supplies an extended path
1001
if not os.path.exists(location):
1045
to_transport = transport.get_transport(location)
1047
# The path has to exist to initialize a
1048
# branch inside of it.
1049
# Just using os.mkdir, since I don't
1050
# believe that we want to create a bunch of
1051
# locations if the user supplies an extended path
1052
# TODO: create-prefix
1054
to_transport.mkdir('.')
1055
except errors.FileExists:
1004
1059
existing_bzrdir = bzrdir.BzrDir.open(location)
1005
1060
except NotBranchError:
1007
1062
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1009
1064
if existing_bzrdir.has_branch():
1010
if existing_bzrdir.has_workingtree():
1011
raise errors.AlreadyBranchError(location)
1013
raise errors.BranchExistsWithoutWorkingTree(location)
1065
if (isinstance(to_transport, LocalTransport)
1066
and not existing_bzrdir.has_workingtree()):
1067
raise errors.BranchExistsWithoutWorkingTree(location)
1068
raise errors.AlreadyBranchError(location)
1015
1070
existing_bzrdir.create_branch()
1016
1071
existing_bzrdir.create_workingtree()
1042
1097
' a working tree')]
1043
1098
aliases = ["init-repo"]
1044
1099
def run(self, location, format=None, trees=False):
1045
from bzrlib.transport import get_transport
1046
1100
if format is None:
1047
1101
format = get_format_type('default')
1048
transport = get_transport(location)
1049
if not transport.has('.'):
1051
newdir = format.initialize_on_transport(transport)
1103
if location is None:
1106
to_transport = transport.get_transport(location)
1108
to_transport.mkdir('.')
1109
except errors.FileExists:
1112
newdir = format.initialize_on_transport(to_transport)
1052
1113
repo = newdir.create_repository(shared=True)
1053
1114
repo.set_make_working_trees(trees)
1056
1117
class cmd_diff(Command):
1057
"""Show differences in working tree.
1118
"""Show differences in the working tree or between revisions.
1059
1120
If files are listed, only the changes in those files are listed.
1060
1121
Otherwise, all changes for the tree are listed.
1128
Shows the difference in the working tree versus the last commit
1130
Difference between the working tree and revision 1
1068
1131
bzr diff -r1..2
1132
Difference between revision 2 and revision 1
1069
1133
bzr diff --diff-prefix old/:new/
1134
Same as 'bzr diff' but prefix paths with old/ and new/
1070
1135
bzr diff bzr.mine bzr.dev
1136
Show the differences between the two working trees
1138
Show just the differences for 'foo.c'
1073
1140
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1074
1141
# or a graphical diff.
1118
1185
# FIXME diff those two files. rbc 20051123
1119
1186
raise BzrCommandError("Files are in different branches")
1120
1187
file_list = None
1188
except NotBranchError:
1189
if (revision is not None and len(revision) == 2
1190
and not revision[0].needs_branch()
1191
and not revision[1].needs_branch()):
1192
# If both revision specs include a branch, we can
1193
# diff them without needing a local working tree
1194
tree1, tree2 = None, None
1121
1197
if revision is not None:
1122
1198
if tree2 is not None:
1123
1199
raise BzrCommandError("Can't specify -r with two branches")
1172
1248
@display_command
1174
from bzrlib.delta import compare_trees
1176
1250
tree = WorkingTree.open_containing(u'.')[0]
1177
td = compare_trees(tree.basis_tree(), tree)
1251
td = tree.changes_from(tree.basis_tree())
1179
1252
for path, id, kind, text_modified, meta_modified in td.modified:
1180
1253
self.outf.write(path + '\n')
1286
1364
elif len(revision) == 1:
1287
1365
rev1 = rev2 = revision[0].in_history(b).revno
1288
1366
elif len(revision) == 2:
1367
if revision[1].get_branch() != revision[0].get_branch():
1368
# b is taken from revision[0].get_branch(), and
1369
# show_log will use its revision_history. Having
1370
# different branches will lead to weird behaviors.
1371
raise BzrCommandError(
1372
"Log doesn't accept two revisions in different branches.")
1289
1373
if revision[0].spec is None:
1290
1374
# missing begin-range means first revision
1306
1390
if rev1 > rev2:
1307
1391
(rev2, rev1) = (rev1, rev2)
1309
if (log_format == None):
1310
default = bzrlib.config.BranchConfig(b).log_format()
1311
log_format = get_log_format(long=long, short=short, line=line, default=default)
1393
if (log_format is None):
1394
default = b.get_config().log_format()
1395
log_format = get_log_format(long=long, short=short, line=line,
1312
1397
lf = log_formatter(log_format,
1313
1398
show_ids=show_ids,
1314
1399
to_file=self.outf,
1350
1435
b = tree.branch
1351
1436
inv = tree.read_working_inventory()
1352
1437
file_id = inv.path2id(relpath)
1353
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
1438
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
1354
1439
self.outf.write("%6d %s\n" % (revno, what))
1436
1520
bzr ignore '*.class'
1438
1522
# TODO: Complain if the filename is absolute
1439
takes_args = ['name_pattern']
1523
takes_args = ['name_pattern?']
1525
Option('old-default-rules',
1526
help='Out the ignore rules bzr < 0.9 always used.')
1441
def run(self, name_pattern):
1529
def run(self, name_pattern=None, old_default_rules=None):
1442
1530
from bzrlib.atomicfile import AtomicFile
1531
if old_default_rules is not None:
1532
# dump the rules and exit
1533
for pattern in ignores.OLD_DEFAULTS:
1536
if name_pattern is None:
1537
raise BzrCommandError("ignore requires a NAME_PATTERN")
1445
1538
tree, relpath = WorkingTree.open_containing(u'.')
1446
1539
ifn = tree.abspath('.bzrignore')
1448
1540
if os.path.exists(ifn):
1449
1541
f = open(ifn, 'rt')
1682
1775
except PointlessCommit:
1683
1776
# FIXME: This should really happen before the file is read in;
1684
1777
# perhaps prepare the commit; get the message; then actually commit
1685
raise BzrCommandError("no changes to commit",
1686
["use --unchanged to commit anyhow"])
1778
raise BzrCommandError("no changes to commit."
1779
" use --unchanged to commit anyhow")
1687
1780
except ConflictsInTree:
1688
1781
raise BzrCommandError("Conflicts detected in working tree. "
1689
1782
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1691
1784
raise BzrCommandError("Commit refused because there are unknown "
1692
1785
"files in the working tree.")
1693
1786
except errors.BoundBranchOutOfDate, e:
1694
raise BzrCommandError(str(e)
1695
+ ' Either unbind, update, or'
1696
' pass --local to commit.')
1787
raise BzrCommandError(str(e) + "\n"
1788
'To commit to master branch, run update and then commit.\n'
1789
'You can also pass --local to commit to continue working '
1699
1792
class cmd_check(Command):
1700
1793
"""Validate consistency of branch history.
1762
1855
class cmd_whoami(Command):
1763
"""Show bzr user id."""
1764
takes_options = ['email']
1856
"""Show or set bzr user id.
1860
bzr whoami 'Frank Chu <fchu@example.com>'
1862
takes_options = [ Option('email',
1863
help='display email address only'),
1865
help='set identity for the current branch instead of '
1868
takes_args = ['name?']
1869
encoding_type = 'replace'
1766
1871
@display_command
1767
def run(self, email=False):
1872
def run(self, email=False, branch=False, name=None):
1874
# use branch if we're inside one; otherwise global config
1876
c = Branch.open_containing('.')[0].get_config()
1877
except NotBranchError:
1878
c = config.GlobalConfig()
1880
self.outf.write(c.user_email() + '\n')
1882
self.outf.write(c.username() + '\n')
1885
# display a warning if an email address isn't included in the given name.
1769
b = WorkingTree.open_containing(u'.')[0].branch
1770
config = bzrlib.config.BranchConfig(b)
1771
except NotBranchError:
1772
config = bzrlib.config.GlobalConfig()
1887
config.extract_email_address(name)
1889
warning('"%s" does not seem to contain an email address. '
1890
'This is allowed, but not recommended.', name)
1775
print config.user_email()
1892
# use global config unless --branch given
1894
c = Branch.open_containing('.')[0].get_config()
1777
print config.username()
1896
c = config.GlobalConfig()
1897
c.set_user_option('email', name)
1780
1900
class cmd_nick(Command):
1849
1969
Option('lsprof-timed',
1850
1970
help='generate lsprof output for benchmarked'
1851
1971
' sections of code.'),
1972
Option('cache-dir', type=str,
1973
help='a directory to cache intermediate'
1974
' benchmark steps'),
1854
1977
def run(self, testspecs_list=None, verbose=None, one=False,
1855
1978
keep_output=False, transport=None, benchmark=None,
1979
lsprof_timed=None, cache_dir=None):
1857
1980
import bzrlib.ui
1858
1981
from bzrlib.tests import selftest
1859
1982
import bzrlib.benchmarks as benchmarks
1983
from bzrlib.benchmarks import tree_creator
1985
if cache_dir is not None:
1986
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
1860
1987
# we don't want progress meters from the tests to go to the
1861
1988
# real output; and we don't want log messages cluttering up
1862
1989
# the real logs.
1863
save_ui = bzrlib.ui.ui_factory
1864
print '%10s: %s' % ('bzr', bzrlib.osutils.realpath(sys.argv[0]))
1990
save_ui = ui.ui_factory
1991
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1865
1992
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1867
bzrlib.trace.info('running tests...')
1994
info('running tests...')
1869
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1996
ui.ui_factory = ui.SilentUIFactory()
1870
1997
if testspecs_list is not None:
1871
1998
pattern = '|'.join(testspecs_list)
1875
2002
test_suite_factory = benchmarks.test_suite
1876
2003
if verbose is None:
2005
benchfile = open(".perf_history", "at")
1879
2007
test_suite_factory = None
1880
2008
if verbose is None:
1881
2009
verbose = False
1882
result = selftest(verbose=verbose,
1884
stop_on_failure=one,
1885
keep_output=keep_output,
1886
transport=transport,
1887
test_suite_factory=test_suite_factory,
1888
lsprof_timed=lsprof_timed)
2012
result = selftest(verbose=verbose,
2014
stop_on_failure=one,
2015
keep_output=keep_output,
2016
transport=transport,
2017
test_suite_factory=test_suite_factory,
2018
lsprof_timed=lsprof_timed,
2019
bench_history=benchfile)
2021
if benchfile is not None:
1890
bzrlib.trace.info('tests passed')
2024
info('tests passed')
1892
bzrlib.trace.info('tests failed')
2026
info('tests failed')
1893
2027
return int(not result)
1895
bzrlib.ui.ui_factory = save_ui
1898
def _get_bzr_branch():
1899
"""If bzr is run from a branch, return Branch or None"""
1900
import bzrlib.errors
1901
from bzrlib.branch import Branch
1902
from bzrlib.osutils import abspath
1903
from os.path import dirname
1906
branch = Branch.open(dirname(abspath(dirname(__file__))))
1908
except bzrlib.errors.BzrError:
1913
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1914
# is bzrlib itself in a branch?
1915
branch = _get_bzr_branch()
1917
rh = branch.revision_history()
1919
print " bzr checkout, revision %d" % (revno,)
1920
print " nick: %s" % (branch.nick,)
1922
print " revid: %s" % (rh[-1],)
1923
print "Using python interpreter:", sys.executable
1925
print "Using python standard library:", os.path.dirname(site.__file__)
1926
print "Using bzrlib:",
1927
if len(bzrlib.__path__) > 1:
1928
# print repr, which is a good enough way of making it clear it's
1929
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1930
print repr(bzrlib.__path__)
1932
print bzrlib.__path__[0]
1935
print bzrlib.__copyright__
1936
print "http://bazaar-vcs.org/"
1938
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
1939
print "you may use, modify and redistribute it under the terms of the GNU"
1940
print "General Public License version 2 or later."
2029
ui.ui_factory = save_ui
1943
2032
class cmd_version(Command):
1944
2033
"""Show version of bzr."""
1945
2035
@display_command
2037
from bzrlib.version import show_version
1949
2041
class cmd_rocks(Command):
1950
2042
"""Statement of optimism."""
1952
2046
@display_command
1954
2048
print "it sure does!"
1957
2051
class cmd_find_merge_base(Command):
1958
"""Find and print a base revision for merging two branches.
2052
"""Find and print a base revision for merging two branches."""
1960
2053
# TODO: Options to specify revisions on either side, as if
1961
2054
# merging only part of the history.
1962
2055
takes_args = ['branch', 'other']
1981
2074
base_rev_id = common_ancestor(last1, last2, source)
1983
2076
print 'merge base is revision %s' % base_rev_id
1987
if base_revno is None:
1988
raise bzrlib.errors.UnrelatedBranches()
1990
print ' r%-6d in %s' % (base_revno, branch)
1992
other_revno = branch2.revision_id_to_revno(base_revid)
1994
print ' r%-6d in %s' % (other_revno, other)
1998
2079
class cmd_merge(Command):
1999
2080
"""Perform a three-way merge.
2001
The branch is the branch you will merge from. By default, it will
2002
merge the latest revision. If you specify a revision, that
2003
revision will be merged. If you specify two revisions, the first
2004
will be used as a BASE, and the second one as OTHER. Revision
2005
numbers are always relative to the specified branch.
2082
The branch is the branch you will merge from. By default, it will merge
2083
the latest revision. If you specify a revision, that revision will be
2084
merged. If you specify two revisions, the first will be used as a BASE,
2085
and the second one as OTHER. Revision numbers are always relative to the
2007
2088
By default, bzr will try to merge in all new work from the other
2008
2089
branch, automatically determining an appropriate base. If this
2038
2120
takes_args = ['branch?']
2039
2121
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2040
2122
Option('show-base', help="Show base revision text in "
2124
Option('uncommitted', help='Apply uncommitted changes'
2125
' from a working copy, instead of branch changes')]
2043
2127
def help(self):
2044
2128
from merge import merge_type_help
2046
2130
return getdoc(self) + '\n' + merge_type_help()
2048
2132
def run(self, branch=None, revision=None, force=False, merge_type=None,
2049
show_base=False, reprocess=False, remember=False):
2133
show_base=False, reprocess=False, remember=False,
2050
2135
if merge_type is None:
2051
2136
merge_type = Merge3Merger
2053
2138
tree = WorkingTree.open_containing(u'.')[0]
2056
if branch is not None:
2057
reader = BundleReader(file(branch, 'rb'))
2061
if e.errno not in (errno.ENOENT, errno.EISDIR):
2066
if reader is not None:
2067
conflicts = merge_bundle(reader, tree, not force, merge_type,
2068
reprocess, show_base)
2140
if branch is not None:
2142
reader = bundle.read_bundle_from_url(branch)
2144
pass # Continue on considering this url a Branch
2146
conflicts = merge_bundle(reader, tree, not force, merge_type,
2147
reprocess, show_base)
2074
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2153
if revision is None \
2154
or len(revision) < 1 or revision[0].needs_branch():
2155
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2076
2157
if revision is None or len(revision) < 1:
2078
other = [branch, -1]
2160
other = [branch, None]
2163
other = [branch, -1]
2079
2164
other_branch, path = Branch.open_containing(branch)
2167
raise BzrCommandError('Cannot use --uncommitted and --revision'
2168
' at the same time.')
2169
branch = revision[0].get_branch() or branch
2081
2170
if len(revision) == 1:
2082
2171
base = [None, None]
2083
2172
other_branch, path = Branch.open_containing(branch)
2087
2176
assert len(revision) == 2
2088
2177
if None in revision:
2089
2178
raise BzrCommandError(
2090
"Merge doesn't permit that revision specifier.")
2091
other_branch, path = Branch.open_containing(branch)
2179
"Merge doesn't permit empty revision specifier.")
2180
base_branch, path = Branch.open_containing(branch)
2181
branch1 = revision[1].get_branch() or branch
2182
other_branch, path1 = Branch.open_containing(branch1)
2183
if revision[0].get_branch() is not None:
2184
# then path was obtained from it, and is None.
2093
base = [branch, revision[0].in_history(other_branch).revno]
2094
other = [branch, revision[1].in_history(other_branch).revno]
2187
base = [branch, revision[0].in_history(base_branch).revno]
2188
other = [branch1, revision[1].in_history(other_branch).revno]
2096
2190
if tree.branch.get_parent() is None or remember:
2097
2191
tree.branch.set_parent(other_branch.base)
2179
2273
tree, file_list = tree_files(file_list)
2180
2274
tree.lock_write()
2182
pending_merges = tree.pending_merges()
2183
if len(pending_merges) != 1:
2276
parents = tree.get_parent_ids()
2277
if len(parents) != 2:
2184
2278
raise BzrCommandError("Sorry, remerge only works after normal"
2185
+ " merges. Not cherrypicking or"
2279
" merges. Not cherrypicking or"
2187
2281
repository = tree.branch.repository
2188
base_revision = common_ancestor(tree.branch.last_revision(),
2189
pending_merges[0], repository)
2282
base_revision = common_ancestor(parents[0],
2283
parents[1], repository)
2190
2284
base_tree = repository.revision_tree(base_revision)
2191
other_tree = repository.revision_tree(pending_merges[0])
2285
other_tree = repository.revision_tree(parents[1])
2192
2286
interesting_ids = None
2288
conflicts = tree.conflicts()
2193
2289
if file_list is not None:
2194
2290
interesting_ids = set()
2195
2291
for filename in file_list:
2203
2299
for name, ie in tree.inventory.iter_entries(file_id):
2204
2300
interesting_ids.add(ie.file_id)
2301
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2205
2302
transform_tree(tree, tree.basis_tree(), interesting_ids)
2303
tree.set_conflicts(ConflictList(new_conflicts))
2206
2304
if file_list is None:
2207
2305
restore_files = list(tree.iter_conflicts())
2212
2310
restore(tree.abspath(filename))
2213
2311
except NotConflicted:
2215
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2217
interesting_ids = interesting_ids,
2218
other_rev_id=pending_merges[0],
2219
merge_type=merge_type,
2220
show_base=show_base,
2221
reprocess=reprocess)
2313
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2315
interesting_ids=interesting_ids,
2316
other_rev_id=parents[1],
2317
merge_type=merge_type,
2318
show_base=show_base,
2319
reprocess=reprocess)
2224
2322
if conflicts > 0:
2430
encoding_type = 'replace'
2334
2433
def run(self, other_branch=None, reverse=False, mine_only=False,
2335
2434
theirs_only=False, log_format=None, long=False, short=False, line=False,
2336
2435
show_ids=False, verbose=False):
2337
2436
from bzrlib.missing import find_unmerged, iter_log_data
2338
2437
from bzrlib.log import log_formatter
2339
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
2438
local_branch = Branch.open_containing(u".")[0]
2340
2439
parent = local_branch.get_parent()
2341
2440
if other_branch is None:
2342
2441
other_branch = parent
2343
2442
if other_branch is None:
2344
raise BzrCommandError("No missing location known or specified.")
2443
raise BzrCommandError("No peer location known or specified.")
2345
2444
print "Using last location: " + local_branch.get_parent()
2346
remote_branch = bzrlib.branch.Branch.open(other_branch)
2445
remote_branch = Branch.open(other_branch)
2347
2446
if remote_branch.base == local_branch.base:
2348
2447
remote_branch = local_branch
2349
2448
local_branch.lock_read()
2351
2450
remote_branch.lock_read()
2353
2452
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2354
if (log_format == None):
2355
default = bzrlib.config.BranchConfig(local_branch).log_format()
2356
log_format = get_log_format(long=long, short=short, line=line, default=default)
2357
lf = log_formatter(log_format, sys.stdout,
2453
if (log_format is None):
2454
default = local_branch.get_config().log_format()
2455
log_format = get_log_format(long=long, short=short,
2456
line=line, default=default)
2457
lf = log_formatter(log_format,
2358
2459
show_ids=show_ids,
2359
2460
show_timezone='original')
2360
2461
if reverse is False:
2403
2504
import bzrlib.plugin
2404
2505
from inspect import getdoc
2405
2506
for name, plugin in bzrlib.plugin.all_plugins().items():
2406
if hasattr(plugin, '__path__'):
2507
if getattr(plugin, '__path__', None) is not None:
2407
2508
print plugin.__path__[0]
2408
elif hasattr(plugin, '__file__'):
2509
elif getattr(plugin, '__file__', None) is not None:
2409
2510
print plugin.__file__
2413
2514
d = getdoc(plugin)
2418
2519
class cmd_testament(Command):
2419
2520
"""Show testament (signing-form) of a revision."""
2420
takes_options = ['revision', 'long']
2521
takes_options = ['revision',
2522
Option('long', help='Produce long-format testament'),
2523
Option('strict', help='Produce a strict-format'
2421
2525
takes_args = ['branch?']
2422
2526
@display_command
2423
def run(self, branch=u'.', revision=None, long=False):
2424
from bzrlib.testament import Testament
2527
def run(self, branch=u'.', revision=None, long=False, strict=False):
2528
from bzrlib.testament import Testament, StrictTestament
2530
testament_class = StrictTestament
2532
testament_class = Testament
2425
2533
b = WorkingTree.open_containing(branch)[0].branch
2450
2558
# TODO: annotate directories; showing when each file was last changed
2451
2559
# TODO: if the working copy is modified, show annotations on that
2452
2560
# with new uncommitted lines marked
2453
aliases = ['blame', 'praise']
2561
aliases = ['ann', 'blame', 'praise']
2454
2562
takes_args = ['filename']
2455
2563
takes_options = [Option('all', help='show annotations on all lines'),
2456
2564
Option('long', help='show date in annotations'),
2487
2595
takes_options = ['revision']
2489
2597
def run(self, revision_id_list=None, revision=None):
2490
import bzrlib.config as config
2491
2598
import bzrlib.gpg as gpg
2492
2599
if revision_id_list is not None and revision is not None:
2493
2600
raise BzrCommandError('You can only supply one of revision_id or --revision')
2494
2601
if revision_id_list is None and revision is None:
2495
2602
raise BzrCommandError('You must supply either --revision or a revision_id')
2496
2603
b = WorkingTree.open_containing(u'.')[0].branch
2497
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
2604
gpg_strategy = gpg.GPGStrategy(b.get_config())
2498
2605
if revision_id_list is not None:
2499
2606
for revision_id in revision_id_list:
2500
2607
b.repository.sign_revision(revision_id, gpg_strategy)
2576
2683
takes_args = ['location?']
2579
def run(self, location=None,
2686
def run(self, location=None,
2580
2687
dry_run=False, verbose=False,
2581
2688
revision=None, force=False):
2582
from bzrlib.branch import Branch
2583
from bzrlib.log import log_formatter
2689
from bzrlib.log import log_formatter, show_log
2585
2691
from bzrlib.uncommit import uncommit
2595
2701
b = control.open_branch()
2597
2704
if revision is None:
2598
2705
revno = b.revno()
2599
rev_id = b.last_revision()
2601
revno, rev_id = revision[0].in_history(b)
2707
# 'bzr uncommit -r 10' actually means uncommit
2708
# so that the final tree is at revno 10.
2709
# but bzrlib.uncommit.uncommit() actually uncommits
2710
# the revisions that are supplied.
2711
# So we need to offset it by one
2712
revno = revision[0].in_history(b).revno+1
2714
if revno <= b.revno():
2715
rev_id = b.get_rev_id(revno)
2602
2716
if rev_id is None:
2603
print 'No revisions to uncommit.'
2605
for r in range(revno, b.revno()+1):
2606
rev_id = b.get_rev_id(r)
2607
lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2608
lf.show(r, b.repository.get_revision(rev_id), None)
2717
self.outf.write('No revisions to uncommit.\n')
2720
lf = log_formatter('short',
2722
show_timezone='original')
2727
direction='forward',
2728
start_revision=revno,
2729
end_revision=b.revno())
2611
2732
print 'Dry-run, pretending to remove the above revisions.'
2770
class cmd_wait_until_signalled(Command):
2771
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
2773
This just prints a line to signal when it is ready, then blocks on stdin.
2779
sys.stdout.write("running\n")
2781
sys.stdin.readline()
2784
class cmd_serve(Command):
2785
"""Run the bzr server.
2789
help='serve on stdin/out for use from inetd or sshd'),
2791
help='listen for connections on nominated port of the form '
2792
'[hostname:]portnumber. Passing 0 as the port number will '
2793
'result in a dynamically allocated port.',
2796
help='serve contents of directory',
2800
def run(self, port=None, inet=False, directory=None):
2801
from bzrlib.transport import smart
2802
from bzrlib.transport import get_transport
2803
if directory is None:
2804
directory = os.getcwd()
2805
t = get_transport(directory)
2807
server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
2808
elif port is not None:
2810
host, port = port.split(':')
2813
server = smart.SmartTCPServer(t, host=host, port=int(port))
2814
print 'listening on port: ', server.port
2817
raise BzrCommandError("bzr serve requires one of --inet or --port")
2650
2821
# command-line interpretation helper for merge-related commands
2651
2822
def merge(other_revision, base_revision,