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
17
17
"""builtin bzr commands"""
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
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
44
from bzrlib.branch import Branch
31
45
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
32
46
from bzrlib.conflicts import ConflictList
47
from bzrlib.revision import common_ancestor
48
from bzrlib.revisionspec import RevisionSpec
49
from bzrlib.workingtree import WorkingTree
33
52
from bzrlib.commands import Command, display_command
34
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
53
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
35
54
NotBranchError, DivergedBranches, NotConflicted,
36
55
NoSuchFile, NoWorkingTree, FileInWrongBranch,
37
56
NotVersionedError, NotABundle)
38
from bzrlib.merge import Merge3Merger
39
57
from bzrlib.option import Option
40
58
from bzrlib.progress import DummyProgress, ProgressPhase
41
from bzrlib.revision import common_ancestor
42
from bzrlib.revisionspec import RevisionSpec
43
59
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
44
60
from bzrlib.transport.local import LocalTransport
45
import bzrlib.urlutils as urlutils
46
from bzrlib.workingtree import WorkingTree
49
63
def tree_files(file_list, default_branch=u'.'):
96
110
format = bzrdir.BzrDirMetaFormat1()
97
111
format.repository_format = repository.RepositoryFormatKnit1()
113
if typestring == "experimental-knit2":
114
format = bzrdir.BzrDirMetaFormat1()
115
format.repository_format = repository.RepositoryFormatKnit2()
99
117
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
100
118
"metaweave and weave" % typestring
101
119
raise BzrCommandError(msg)
264
282
--dry-run will show which files would be added, but not actually
285
--file-ids-from will try to use the file ids from the supplied path.
286
It looks up ids trying to find a matching parent directory with the
287
same filename, and then by pure path.
267
289
takes_args = ['file*']
268
takes_options = ['no-recurse', 'dry-run', 'verbose']
290
takes_options = ['no-recurse', 'dry-run', 'verbose',
291
Option('file-ids-from', type=unicode,
292
help='Lookup file ids from here')]
269
293
encoding_type = 'replace'
271
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
295
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
272
297
import bzrlib.add
274
action = bzrlib.add.AddAction(to_file=self.outf,
275
should_print=(not is_quiet()))
277
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
299
if file_ids_from is not None:
301
base_tree, base_path = WorkingTree.open_containing(
303
except errors.NoWorkingTree:
304
base_branch, base_path = Branch.open_containing(
306
base_tree = base_branch.basis_tree()
308
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
309
to_file=self.outf, should_print=(not is_quiet()))
311
action = bzrlib.add.AddAction(to_file=self.outf,
312
should_print=(not is_quiet()))
314
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
278
315
action=action, save=not dry_run)
279
316
if len(ignored) > 0:
327
364
"""Show inventory of the current working copy or a revision.
329
366
It is possible to limit the output to a particular entry
330
type using the --kind option. For example; --kind file.
367
type using the --kind option. For example: --kind file.
369
It is also possible to restrict the list of files to a specific
370
set. For example: bzr inventory --show-ids this/file
333
373
takes_options = ['revision', 'show-ids', 'kind']
374
takes_args = ['file*']
336
def run(self, revision=None, show_ids=False, kind=None):
377
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
337
378
if kind and kind not in ['file', 'directory', 'symlink']:
338
379
raise BzrCommandError('invalid kind specified')
339
tree = WorkingTree.open_containing(u'.')[0]
341
inv = tree.read_working_inventory()
381
work_tree, file_list = tree_files(file_list)
383
if revision is not None:
343
384
if len(revision) > 1:
344
385
raise BzrCommandError('bzr inventory --revision takes'
345
' exactly one revision identifier')
346
inv = tree.branch.repository.get_revision_inventory(
347
revision[0].in_history(tree.branch).rev_id)
349
for path, entry in inv.entries():
386
' exactly one revision identifier')
387
revision_id = revision[0].in_history(work_tree.branch).rev_id
388
tree = work_tree.branch.repository.revision_tree(revision_id)
390
# We include work_tree as well as 'tree' here
391
# So that doing '-r 10 path/foo' will lookup whatever file
392
# exists now at 'path/foo' even if it has been renamed, as
393
# well as whatever files existed in revision 10 at path/foo
394
trees = [tree, work_tree]
399
if file_list is not None:
400
file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
401
require_versioned=True)
402
# find_ids_across_trees may include some paths that don't
404
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
405
for file_id in file_ids if file_id in tree)
407
entries = tree.inventory.entries()
409
for path, entry in entries:
350
410
if kind and kind != entry.kind:
538
597
br_to = dir_to.open_branch()
539
598
except NotBranchError:
540
599
# create a branch.
541
transport = transport.clone('..')
600
to_transport = to_transport.clone('..')
542
601
if not create_prefix:
544
relurl = transport.relpath(location_url)
603
relurl = to_transport.relpath(location_url)
545
604
mutter('creating directory %s => %s', location_url, relurl)
546
transport.mkdir(relurl)
605
to_transport.mkdir(relurl)
547
606
except NoSuchFile:
548
607
raise BzrCommandError("Parent directory of %s "
549
608
"does not exist." % location)
551
current = transport.base
552
needed = [(transport, transport.relpath(location_url))]
610
current = to_transport.base
611
needed = [(to_transport, to_transport.relpath(location_url))]
555
transport, relpath = needed[-1]
556
transport.mkdir(relpath)
614
to_transport, relpath = needed[-1]
615
to_transport.mkdir(relpath)
558
617
except NoSuchFile:
559
new_transport = transport.clone('..')
618
new_transport = to_transport.clone('..')
560
619
needed.append((new_transport,
561
new_transport.relpath(transport.base)))
562
if new_transport.base == transport.base:
620
new_transport.relpath(to_transport.base)))
621
if new_transport.base == to_transport.base:
563
622
raise BzrCommandError("Could not create "
565
624
dir_to = br_from.bzrdir.clone(location_url,
753
811
old_format = bzrdir.BzrDirFormat.get_default_format()
754
812
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
757
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
758
branch.BranchReferenceFormat().initialize(checkout, source)
760
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
761
to_location, force_new_tree=False)
762
checkout = checkout_branch.bzrdir
763
checkout_branch.bind(source)
764
if revision_id is not None:
765
rh = checkout_branch.revision_history()
766
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
767
checkout.create_workingtree(revision_id)
814
source.create_checkout(to_location, revision_id, lightweight)
769
816
bzrdir.BzrDirFormat.set_default_format(old_format)
781
828
def run(self, dir=u'.'):
782
from bzrlib.tree import find_renames
783
829
tree = WorkingTree.open_containing(dir)[0]
784
830
old_inv = tree.basis_tree().inventory
785
831
new_inv = tree.read_working_inventory()
786
renames = list(find_renames(old_inv, new_inv))
832
renames = list(_mod_tree.find_renames(old_inv, new_inv))
788
834
for old_name, new_name in renames:
789
835
self.outf.write("%s => %s\n" % (old_name, new_name))
800
846
'bzr revert' instead of 'bzr commit' after the update.
802
848
takes_args = ['dir?']
804
851
def run(self, dir='.'):
805
852
tree = WorkingTree.open_containing(dir)[0]
806
853
tree.lock_write()
808
last_rev = tree.last_revision()
855
existing_pending_merges = tree.get_parent_ids()[1:]
856
last_rev = tree.last_revision()
809
857
if last_rev == tree.branch.last_revision():
810
858
# may be up to date, check master too.
811
859
master = tree.branch.get_master_branch()
866
917
raise BzrCommandError('Specify one or more files to remove, or'
869
from bzrlib.delta import compare_trees
870
added = [compare_trees(tree.basis_tree(), tree,
871
specific_files=file_list).added]
872
file_list = sorted([f[0] for f in added[0]], reverse=True)
920
added = tree.changes_from(tree.basis_tree(),
921
specific_files=file_list).added
922
file_list = sorted([f[0] for f in added], reverse=True)
873
923
if len(file_list) == 0:
874
924
raise BzrCommandError('No matching files.')
875
925
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1016
1066
format = get_format_type('default')
1017
1067
if location is None:
1018
1068
location = u'.'
1020
# The path has to exist to initialize a
1021
# branch inside of it.
1022
# Just using os.mkdir, since I don't
1023
# believe that we want to create a bunch of
1024
# locations if the user supplies an extended path
1025
if not os.path.exists(location):
1070
to_transport = transport.get_transport(location)
1072
# The path has to exist to initialize a
1073
# branch inside of it.
1074
# Just using os.mkdir, since I don't
1075
# believe that we want to create a bunch of
1076
# locations if the user supplies an extended path
1077
# TODO: create-prefix
1079
to_transport.mkdir('.')
1080
except errors.FileExists:
1028
1084
existing_bzrdir = bzrdir.BzrDir.open(location)
1029
1085
except NotBranchError:
1031
1087
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1033
1089
if existing_bzrdir.has_branch():
1034
if existing_bzrdir.has_workingtree():
1035
raise errors.AlreadyBranchError(location)
1037
raise errors.BranchExistsWithoutWorkingTree(location)
1090
if (isinstance(to_transport, LocalTransport)
1091
and not existing_bzrdir.has_workingtree()):
1092
raise errors.BranchExistsWithoutWorkingTree(location)
1093
raise errors.AlreadyBranchError(location)
1039
1095
existing_bzrdir.create_branch()
1040
1096
existing_bzrdir.create_workingtree()
1066
1122
' a working tree')]
1067
1123
aliases = ["init-repo"]
1068
1124
def run(self, location, format=None, trees=False):
1069
from bzrlib.transport import get_transport
1070
1125
if format is None:
1071
1126
format = get_format_type('default')
1072
transport = get_transport(location)
1073
if not transport.has('.'):
1075
newdir = format.initialize_on_transport(transport)
1128
if location is None:
1131
to_transport = transport.get_transport(location)
1133
to_transport.mkdir('.')
1134
except errors.FileExists:
1137
newdir = format.initialize_on_transport(to_transport)
1076
1138
repo = newdir.create_repository(shared=True)
1077
1139
repo.set_make_working_trees(trees)
1149
1211
raise BzrCommandError("Files are in different branches")
1150
1212
file_list = None
1151
1213
except NotBranchError:
1152
# Don't raise an error when bzr diff is called from
1153
# outside a working tree.
1154
tree1, tree2 = None, None
1214
if (revision is not None and len(revision) == 2
1215
and not revision[0].needs_branch()
1216
and not revision[1].needs_branch()):
1217
# If both revision specs include a branch, we can
1218
# diff them without needing a local working tree
1219
tree1, tree2 = None, None
1155
1222
if revision is not None:
1156
1223
if tree2 is not None:
1157
1224
raise BzrCommandError("Can't specify -r with two branches")
1320
1389
elif len(revision) == 1:
1321
1390
rev1 = rev2 = revision[0].in_history(b).revno
1322
1391
elif len(revision) == 2:
1392
if revision[1].get_branch() != revision[0].get_branch():
1393
# b is taken from revision[0].get_branch(), and
1394
# show_log will use its revision_history. Having
1395
# different branches will lead to weird behaviors.
1396
raise BzrCommandError(
1397
"Log doesn't accept two revisions in different branches.")
1323
1398
if revision[0].spec is None:
1324
1399
# missing begin-range means first revision
1732
1809
raise BzrCommandError("Commit refused because there are unknown "
1733
1810
"files in the working tree.")
1734
1811
except errors.BoundBranchOutOfDate, e:
1735
raise BzrCommandError(str(e)
1736
+ ' Either unbind, update, or'
1737
' pass --local to commit.')
1812
raise BzrCommandError(str(e) + "\n"
1813
'To commit to master branch, run update and then commit.\n'
1814
'You can also pass --local to commit to continue working '
1740
1817
class cmd_check(Command):
1741
1818
"""Validate consistency of branch history.
1917
1994
Option('lsprof-timed',
1918
1995
help='generate lsprof output for benchmarked'
1919
1996
' sections of code.'),
1997
Option('cache-dir', type=str,
1998
help='a directory to cache intermediate'
1999
' benchmark steps'),
1922
2002
def run(self, testspecs_list=None, verbose=None, one=False,
1923
2003
keep_output=False, transport=None, benchmark=None,
2004
lsprof_timed=None, cache_dir=None):
1925
2005
import bzrlib.ui
1926
2006
from bzrlib.tests import selftest
1927
2007
import bzrlib.benchmarks as benchmarks
2008
from bzrlib.benchmarks import tree_creator
2010
if cache_dir is not None:
2011
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
1928
2012
# we don't want progress meters from the tests to go to the
1929
2013
# real output; and we don't want log messages cluttering up
1930
2014
# the real logs.
1943
2027
test_suite_factory = benchmarks.test_suite
1944
2028
if verbose is None:
2030
# TODO: should possibly lock the history file...
2031
benchfile = open(".perf_history", "at")
1947
2033
test_suite_factory = None
1948
2034
if verbose is None:
1949
2035
verbose = False
1950
result = selftest(verbose=verbose,
1952
stop_on_failure=one,
1953
keep_output=keep_output,
1954
transport=transport,
1955
test_suite_factory=test_suite_factory,
1956
lsprof_timed=lsprof_timed)
2038
result = selftest(verbose=verbose,
2040
stop_on_failure=one,
2041
keep_output=keep_output,
2042
transport=transport,
2043
test_suite_factory=test_suite_factory,
2044
lsprof_timed=lsprof_timed,
2045
bench_history=benchfile)
2047
if benchfile is not None:
1958
2050
info('tests passed')
1963
2055
ui.ui_factory = save_ui
1966
def _get_bzr_branch():
1967
"""If bzr is run from a branch, return Branch or None"""
1968
from os.path import dirname
1971
branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1973
except errors.BzrError:
1979
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1980
# is bzrlib itself in a branch?
1981
branch = _get_bzr_branch()
1983
rh = branch.revision_history()
1985
print " bzr checkout, revision %d" % (revno,)
1986
print " nick: %s" % (branch.nick,)
1988
print " revid: %s" % (rh[-1],)
1989
print "Using python interpreter:", sys.executable
1991
print "Using python standard library:", os.path.dirname(site.__file__)
1992
print "Using bzrlib:",
1993
if len(bzrlib.__path__) > 1:
1994
# print repr, which is a good enough way of making it clear it's
1995
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1996
print repr(bzrlib.__path__)
1998
print bzrlib.__path__[0]
2001
print bzrlib.__copyright__
2002
print "http://bazaar-vcs.org/"
2004
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
2005
print "you may use, modify and redistribute it under the terms of the GNU"
2006
print "General Public License version 2 or later."
2009
2058
class cmd_version(Command):
2010
2059
"""Show version of bzr."""
2011
2061
@display_command
2063
from bzrlib.version import show_version
2015
2067
class cmd_rocks(Command):
2016
2068
"""Statement of optimism."""
2018
2072
@display_command
2020
2074
print "it sure does!"
2023
2077
class cmd_find_merge_base(Command):
2024
"""Find and print a base revision for merging two branches.
2078
"""Find and print a base revision for merging two branches."""
2026
2079
# TODO: Options to specify revisions on either side, as if
2027
2080
# merging only part of the history.
2028
2081
takes_args = ['branch', 'other']
2093
2146
takes_args = ['branch?']
2094
2147
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2095
2148
Option('show-base', help="Show base revision text in "
2150
Option('uncommitted', help='Apply uncommitted changes'
2151
' from a working copy, instead of branch changes')]
2098
2153
def help(self):
2099
from merge import merge_type_help
2100
2154
from inspect import getdoc
2101
return getdoc(self) + '\n' + merge_type_help()
2155
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2103
2157
def run(self, branch=None, revision=None, force=False, merge_type=None,
2104
show_base=False, reprocess=False, remember=False):
2158
show_base=False, reprocess=False, remember=False,
2105
2160
if merge_type is None:
2106
merge_type = Merge3Merger
2161
merge_type = _mod_merge.Merge3Merger
2108
2163
tree = WorkingTree.open_containing(u'.')[0]
2123
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2178
if revision is None \
2179
or len(revision) < 1 or revision[0].needs_branch():
2180
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2125
2182
if revision is None or len(revision) < 1:
2127
other = [branch, -1]
2185
other = [branch, None]
2188
other = [branch, -1]
2128
2189
other_branch, path = Branch.open_containing(branch)
2192
raise BzrCommandError('Cannot use --uncommitted and --revision'
2193
' at the same time.')
2194
branch = revision[0].get_branch() or branch
2130
2195
if len(revision) == 1:
2131
2196
base = [None, None]
2132
2197
other_branch, path = Branch.open_containing(branch)
2136
2201
assert len(revision) == 2
2137
2202
if None in revision:
2138
2203
raise BzrCommandError(
2139
"Merge doesn't permit that revision specifier.")
2140
other_branch, path = Branch.open_containing(branch)
2204
"Merge doesn't permit empty revision specifier.")
2205
base_branch, path = Branch.open_containing(branch)
2206
branch1 = revision[1].get_branch() or branch
2207
other_branch, path1 = Branch.open_containing(branch1)
2208
if revision[0].get_branch() is not None:
2209
# then path was obtained from it, and is None.
2142
base = [branch, revision[0].in_history(other_branch).revno]
2143
other = [branch, revision[1].in_history(other_branch).revno]
2212
base = [branch, revision[0].in_history(base_branch).revno]
2213
other = [branch1, revision[1].in_history(other_branch).revno]
2145
2215
if tree.branch.get_parent() is None or remember:
2146
2216
tree.branch.set_parent(other_branch.base)
2152
2222
pb = ui.ui_factory.nested_progress_bar()
2155
conflict_count = merge(other, base, check_clean=(not force),
2156
merge_type=merge_type,
2157
reprocess=reprocess,
2158
show_base=show_base,
2159
pb=pb, file_list=interesting_files)
2225
conflict_count = _merge_helper(
2226
other, base, check_clean=(not force),
2227
merge_type=merge_type,
2228
reprocess=reprocess,
2229
show_base=show_base,
2230
pb=pb, file_list=interesting_files)
2162
2233
if conflict_count != 0:
2218
2289
def help(self):
2219
from merge import merge_type_help
2220
2290
from inspect import getdoc
2221
return getdoc(self) + '\n' + merge_type_help()
2291
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2223
2293
def run(self, file_list=None, merge_type=None, show_base=False,
2224
2294
reprocess=False):
2225
from bzrlib.merge import merge_inner, transform_tree
2226
2295
if merge_type is None:
2227
merge_type = Merge3Merger
2296
merge_type = _mod_merge.Merge3Merger
2228
2297
tree, file_list = tree_files(file_list)
2229
2298
tree.lock_write()
2231
pending_merges = tree.pending_merges()
2232
if len(pending_merges) != 1:
2300
parents = tree.get_parent_ids()
2301
if len(parents) != 2:
2233
2302
raise BzrCommandError("Sorry, remerge only works after normal"
2234
2303
" merges. Not cherrypicking or"
2235
2304
" multi-merges.")
2236
2305
repository = tree.branch.repository
2237
base_revision = common_ancestor(tree.branch.last_revision(),
2238
pending_merges[0], repository)
2306
base_revision = common_ancestor(parents[0],
2307
parents[1], repository)
2239
2308
base_tree = repository.revision_tree(base_revision)
2240
other_tree = repository.revision_tree(pending_merges[0])
2309
other_tree = repository.revision_tree(parents[1])
2241
2310
interesting_ids = None
2242
2311
new_conflicts = []
2243
2312
conflicts = tree.conflicts()
2254
2323
for name, ie in tree.inventory.iter_entries(file_id):
2255
2324
interesting_ids.add(ie.file_id)
2256
2325
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2257
transform_tree(tree, tree.basis_tree(), interesting_ids)
2326
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2258
2327
tree.set_conflicts(ConflictList(new_conflicts))
2259
2328
if file_list is None:
2260
2329
restore_files = list(tree.iter_conflicts())
2265
2334
restore(tree.abspath(filename))
2266
2335
except NotConflicted:
2268
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2270
interesting_ids=interesting_ids,
2271
other_rev_id=pending_merges[0],
2272
merge_type=merge_type,
2273
show_base=show_base,
2274
reprocess=reprocess)
2337
conflicts = _mod_merge.merge_inner(
2338
tree.branch, other_tree, base_tree,
2340
interesting_ids=interesting_ids,
2341
other_rev_id=parents[1],
2342
merge_type=merge_type,
2343
show_base=show_base,
2344
reprocess=reprocess)
2277
2347
if conflicts > 0:
2282
2352
class cmd_revert(Command):
2283
"""Reverse all changes since the last commit.
2285
Only versioned files are affected. Specify filenames to revert only
2286
those files. By default, any files that are changed will be backed up
2287
first. Backup files have a '~' appended to their name.
2353
"""Revert files to a previous revision.
2355
Giving a list of files will revert only those files. Otherwise, all files
2356
will be reverted. If the revision is not specified with '--revision', the
2357
last committed revision is used.
2359
To remove only some changes, without reverting to a prior version, use
2360
merge instead. For example, "merge . --r-2..-3" will remove the changes
2361
introduced by -2, without affecting the changes introduced by -1. Or
2362
to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
2364
By default, any files that have been manually changed will be backed up
2365
first. (Files changed only by merge are not backed up.) Backup files have
2366
'.~#~' appended to their name, where # is a number.
2368
When you provide files, you can use their current pathname or the pathname
2369
from the target revision. So you can use revert to "undelete" a file by
2370
name. If you name a directory, all the contents of that directory will be
2289
2373
takes_options = ['revision', 'no-backup']
2290
2374
takes_args = ['file*']
2291
2375
aliases = ['merge-revert']
2293
2377
def run(self, revision=None, no_backup=False, file_list=None):
2294
from bzrlib.commands import parse_spec
2295
2378
if file_list is not None:
2296
2379
if len(file_list) == 0:
2297
2380
raise BzrCommandError("No files specified")
2459
2542
import bzrlib.plugin
2460
2543
from inspect import getdoc
2461
2544
for name, plugin in bzrlib.plugin.all_plugins().items():
2462
if hasattr(plugin, '__path__'):
2545
if getattr(plugin, '__path__', None) is not None:
2463
2546
print plugin.__path__[0]
2464
elif hasattr(plugin, '__file__'):
2547
elif getattr(plugin, '__file__', None) is not None:
2465
2548
print plugin.__file__
2469
2552
d = getdoc(plugin)
2474
2557
class cmd_testament(Command):
2475
2558
"""Show testament (signing-form) of a revision."""
2476
takes_options = ['revision', 'long',
2559
takes_options = ['revision',
2560
Option('long', help='Produce long-format testament'),
2477
2561
Option('strict', help='Produce a strict-format'
2479
2563
takes_args = ['branch?']
2808
class cmd_wait_until_signalled(Command):
2809
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
2811
This just prints a line to signal when it is ready, then blocks on stdin.
2817
sys.stdout.write("running\n")
2819
sys.stdin.readline()
2822
class cmd_serve(Command):
2823
"""Run the bzr server."""
2825
aliases = ['server']
2829
help='serve on stdin/out for use from inetd or sshd'),
2831
help='listen for connections on nominated port of the form '
2832
'[hostname:]portnumber. Passing 0 as the port number will '
2833
'result in a dynamically allocated port.',
2836
help='serve contents of directory',
2838
Option('allow-writes',
2839
help='By default the server is a readonly server. Supplying '
2840
'--allow-writes enables write access to the contents of '
2841
'the served directory and below. '
2845
def run(self, port=None, inet=False, directory=None, allow_writes=False):
2846
from bzrlib.transport import smart
2847
from bzrlib.transport import get_transport
2848
if directory is None:
2849
directory = os.getcwd()
2850
url = urlutils.local_path_to_url(directory)
2851
if not allow_writes:
2852
url = 'readonly+' + url
2853
t = get_transport(url)
2855
server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
2856
elif port is not None:
2858
host, port = port.split(':')
2861
server = smart.SmartTCPServer(t, host=host, port=int(port))
2862
print 'listening on port: ', server.port
2865
raise BzrCommandError("bzr serve requires one of --inet or --port")
2725
2869
# command-line interpretation helper for merge-related commands
2726
def merge(other_revision, base_revision,
2727
check_clean=True, ignore_zero=False,
2728
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2729
file_list=None, show_base=False, reprocess=False,
2730
pb=DummyProgress()):
2870
def _merge_helper(other_revision, base_revision,
2871
check_clean=True, ignore_zero=False,
2872
this_dir=None, backup_files=False,
2874
file_list=None, show_base=False, reprocess=False,
2875
pb=DummyProgress()):
2731
2876
"""Merge changes into a tree.
2755
2900
clients might prefer to call merge.merge_inner(), which has less magic
2758
from bzrlib.merge import Merger
2903
# Loading it late, so that we don't always have to import bzrlib.merge
2904
if merge_type is None:
2905
merge_type = _mod_merge.Merge3Merger
2759
2906
if this_dir is None:
2760
2907
this_dir = u'.'
2761
2908
this_tree = WorkingTree.open_containing(this_dir)[0]
2762
if show_base and not merge_type is Merge3Merger:
2909
if show_base and not merge_type is _mod_merge.Merge3Merger:
2763
2910
raise BzrCommandError("Show-base is not supported for this merge"
2764
2911
" type. %s" % merge_type)
2765
2912
if reprocess and not merge_type.supports_reprocess:
2768
2915
if reprocess and show_base:
2769
2916
raise BzrCommandError("Cannot do conflict reduction and show base.")
2771
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2918
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
2772
2920
merger.pp = ProgressPhase("Merge phase", 5, pb)
2773
2921
merger.pp.next_phase()
2774
2922
merger.check_basis(check_clean)
2791
2939
return conflicts
2943
merge = _merge_helper
2794
2946
# these get imported and then picked up by the scan for cmd_*
2795
2947
# TODO: Some more consistent way to split command definitions across files;
2796
2948
# we do need to load at least some information about them to know of
2797
2949
# aliases. ideally we would avoid loading the implementation until the
2798
2950
# details were needed.
2951
from bzrlib.cmd_version_info import cmd_version_info
2799
2952
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2800
2953
from bzrlib.bundle.commands import cmd_bundle_revisions
2801
2954
from bzrlib.sign_my_commits import cmd_sign_my_commits