41
from bzrlib.branch import Branch, BranchReferenceFormat
42
from bzrlib.bundle import read_bundle_from_url
45
from bzrlib.branch import Branch
43
46
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
44
47
from bzrlib.conflicts import ConflictList
48
from bzrlib.revision import common_ancestor
49
from bzrlib.revisionspec import RevisionSpec
50
from bzrlib.workingtree import WorkingTree
45
53
from bzrlib.commands import Command, display_command
46
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
47
NotBranchError, DivergedBranches, NotConflicted,
48
NoSuchFile, NoWorkingTree, FileInWrongBranch,
49
NotVersionedError, NotABundle)
50
from bzrlib.merge import Merge3Merger
51
from bzrlib.option import Option
54
from bzrlib.option import Option, RegistryOption
52
55
from bzrlib.progress import DummyProgress, ProgressPhase
53
from bzrlib.revision import common_ancestor
54
from bzrlib.revisionspec import RevisionSpec
55
56
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
56
from bzrlib.transport.local import LocalTransport
58
from bzrlib.workingtree import WorkingTree
61
59
def tree_files(file_list, default_branch=u'.'):
63
61
return internal_tree_files(file_list, default_branch)
64
except FileInWrongBranch, e:
65
raise BzrCommandError("%s is not in the same branch as %s" %
66
(e.path, file_list[0]))
62
except errors.FileInWrongBranch, e:
63
raise errors.BzrCommandError("%s is not in the same branch as %s" %
64
(e.path, file_list[0]))
69
67
# XXX: Bad function name; should possibly also be a class method of
79
77
:param file_list: Filenames to convert.
81
:param default_branch: Fallback tree path to use if file_list is empty or None.
79
:param default_branch: Fallback tree path to use if file_list is empty or
83
82
:return: workingtree, [relative_paths]
85
84
if file_list is None or len(file_list) == 0:
86
85
return WorkingTree.open_containing(default_branch)[0], file_list
87
tree = WorkingTree.open_containing(file_list[0])[0]
86
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
89
88
for filename in file_list:
91
new_list.append(tree.relpath(filename))
90
new_list.append(tree.relpath(osutils.dereference_path(filename)))
92
91
except errors.PathNotChild:
93
raise FileInWrongBranch(tree.branch, filename)
92
raise errors.FileInWrongBranch(tree.branch, filename)
94
93
return tree, new_list
97
96
def get_format_type(typestring):
98
97
"""Parse and return a format specifier."""
99
if typestring == "weave":
100
return bzrdir.BzrDirFormat6()
98
# Have to use BzrDirMetaFormat1 directly, so that
99
# RepositoryFormat.set_default_format works
101
100
if typestring == "default":
102
101
return bzrdir.BzrDirMetaFormat1()
103
if typestring == "metaweave":
104
format = bzrdir.BzrDirMetaFormat1()
105
format.repository_format = repository.RepositoryFormat7()
107
if typestring == "knit":
108
format = bzrdir.BzrDirMetaFormat1()
109
format.repository_format = repository.RepositoryFormatKnit1()
111
if typestring == "experimental-knit2":
112
format = bzrdir.BzrDirMetaFormat1()
113
format.repository_format = repository.RepositoryFormatKnit2()
115
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
116
"metaweave and weave" % typestring
117
raise BzrCommandError(msg)
103
return bzrdir.format_registry.make_bzrdir(typestring)
105
msg = 'Unknown bzr format "%s". See "bzr help formats".' % typestring
106
raise errors.BzrCommandError(msg)
120
109
# TODO: Make sure no commands unconditionally use the working directory as a
129
118
This reports on versioned and unknown files, reporting them
130
119
grouped by state. Possible states are:
133
122
Versioned in the working copy but not in the previous revision.
136
125
Versioned in the previous revision but removed or deleted
137
126
in the working copy.
140
129
Path of this file changed from the previous revision;
141
130
the text may also have changed. This includes files whose
142
131
parent directory was renamed.
145
134
Text has changed since the previous revision.
148
137
Not versioned and not matching an ignore pattern.
150
139
To see ignored files use 'bzr ignored'. For details in the
151
140
changes to file texts, use 'bzr diff'.
142
--short gives a one character status flag for each item, similar
143
to the SVN's status command.
153
145
If no arguments are specified, the status of the entire working
154
146
directory is shown. Otherwise, only the status of the specified
162
154
# TODO: --no-recurse, --recurse options
164
156
takes_args = ['file*']
165
takes_options = ['show-ids', 'revision']
157
takes_options = ['show-ids', 'revision', 'short']
166
158
aliases = ['st', 'stat']
168
160
encoding_type = 'replace'
171
def run(self, show_ids=False, file_list=None, revision=None):
163
def run(self, show_ids=False, file_list=None, revision=None, short=False):
172
164
from bzrlib.status import show_tree_status
174
166
tree, file_list = tree_files(file_list)
176
168
show_tree_status(tree, show_ids=show_ids,
177
169
specific_files=file_list, revision=revision,
181
174
class cmd_cat_revision(Command):
195
188
def run(self, revision_id=None, revision=None):
197
190
if revision_id is not None and revision is not None:
198
raise BzrCommandError('You can only supply one of revision_id or --revision')
191
raise errors.BzrCommandError('You can only supply one of'
192
' revision_id or --revision')
199
193
if revision_id is None and revision is None:
200
raise BzrCommandError('You must supply either --revision or a revision_id')
194
raise errors.BzrCommandError('You must supply either'
195
' --revision or a revision_id')
201
196
b = WorkingTree.open_containing(u'.')[0].branch
203
198
# TODO: jam 20060112 should cat-revision always output utf-8?
206
201
elif revision is not None:
207
202
for rev in revision:
209
raise BzrCommandError('You cannot specify a NULL revision.')
204
raise errors.BzrCommandError('You cannot specify a NULL'
210
206
revno, rev_id = rev.in_history(b)
211
207
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
210
class cmd_remove_tree(Command):
211
"""Remove the working tree from a given branch/checkout.
213
Since a lightweight checkout is little more than a working tree
214
this will refuse to run against one.
219
takes_args = ['location?']
221
def run(self, location='.'):
222
d = bzrdir.BzrDir.open(location)
225
working = d.open_workingtree()
226
except errors.NoWorkingTree:
227
raise errors.BzrCommandError("No working tree to remove")
228
except errors.NotLocalUrl:
229
raise errors.BzrCommandError("You cannot remove the working tree of a "
232
working_path = working.bzrdir.root_transport.base
233
branch_path = working.branch.bzrdir.root_transport.base
234
if working_path != branch_path:
235
raise errors.BzrCommandError("You cannot remove the working tree from "
236
"a lightweight checkout")
238
d.destroy_workingtree()
214
241
class cmd_revno(Command):
215
242
"""Show current revision number.
375
402
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
376
403
if kind and kind not in ['file', 'directory', 'symlink']:
377
raise BzrCommandError('invalid kind specified')
404
raise errors.BzrCommandError('invalid kind specified')
379
406
work_tree, file_list = tree_files(file_list)
381
408
if revision is not None:
382
409
if len(revision) > 1:
383
raise BzrCommandError('bzr inventory --revision takes'
384
' exactly one revision identifier')
410
raise errors.BzrCommandError('bzr inventory --revision takes'
411
' exactly one revision identifier')
385
412
revision_id = revision[0].in_history(work_tree.branch).rev_id
386
413
tree = work_tree.branch.repository.revision_tree(revision_id)
601
629
relurl = to_transport.relpath(location_url)
602
630
mutter('creating directory %s => %s', location_url, relurl)
603
631
to_transport.mkdir(relurl)
605
raise BzrCommandError("Parent directory of %s "
606
"does not exist." % location)
632
except errors.NoSuchFile:
633
raise errors.BzrCommandError("Parent directory of %s "
634
"does not exist." % location)
608
636
current = to_transport.base
609
637
needed = [(to_transport, to_transport.relpath(location_url))]
612
640
to_transport, relpath = needed[-1]
613
641
to_transport.mkdir(relpath)
643
except errors.NoSuchFile:
616
644
new_transport = to_transport.clone('..')
617
645
needed.append((new_transport,
618
646
new_transport.relpath(to_transport.base)))
619
647
if new_transport.base == to_transport.base:
620
raise BzrCommandError("Could not create "
648
raise errors.BzrCommandError("Could not create "
622
650
dir_to = br_from.bzrdir.clone(location_url,
623
651
revision_id=br_from.last_revision())
624
652
br_to = dir_to.open_branch()
639
667
warning('This transport does not update the working '
640
668
'tree of: %s' % (br_to.base,))
641
669
count = br_to.pull(br_from, overwrite)
642
except NoWorkingTree:
670
except errors.NoWorkingTree:
643
671
count = br_to.pull(br_from, overwrite)
645
673
count = tree_to.pull(br_from, overwrite)
646
except DivergedBranches:
647
raise BzrCommandError("These branches have diverged."
648
" Try a merge then push with overwrite.")
674
except errors.DivergedBranches:
675
raise errors.BzrCommandError('These branches have diverged.'
676
' Try using "merge" and then "push".')
649
677
note('%d revision(s) pushed.' % (count,))
712
740
to_transport.mkdir('.')
713
741
except errors.FileExists:
714
raise BzrCommandError('Target directory "%s" already'
715
' exists.' % to_location)
742
raise errors.BzrCommandError('Target directory "%s" already'
743
' exists.' % to_location)
716
744
except errors.NoSuchFile:
717
raise BzrCommandError('Parent of "%s" does not exist.' %
745
raise errors.BzrCommandError('Parent of "%s" does not exist.'
720
748
# preserve whatever source format we have.
721
749
dir = br_from.bzrdir.sprout(to_transport.base,
724
752
except errors.NoSuchRevision:
725
753
to_transport.delete_tree('.')
726
754
msg = "The branch %s has no revision %s." % (from_location, revision[0])
727
raise BzrCommandError(msg)
755
raise errors.BzrCommandError(msg)
728
756
except errors.UnlistableBranch:
729
757
osutils.rmtree(to_location)
730
758
msg = "The branch %s cannot be used as a --basis" % (basis,)
731
raise BzrCommandError(msg)
759
raise errors.BzrCommandError(msg)
733
761
branch.control_files.put_utf8('branch-name', name)
734
762
note('Branched %d revision(s).' % branch.revno())
799
827
os.mkdir(to_location)
800
828
except OSError, e:
801
829
if e.errno == errno.EEXIST:
802
raise BzrCommandError('Target directory "%s" already'
803
' exists.' % to_location)
830
raise errors.BzrCommandError('Target directory "%s" already'
831
' exists.' % to_location)
804
832
if e.errno == errno.ENOENT:
805
raise BzrCommandError('Parent of "%s" does not exist.' %
833
raise errors.BzrCommandError('Parent of "%s" does not exist.'
809
old_format = bzrdir.BzrDirFormat.get_default_format()
810
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
812
source.create_checkout(to_location, revision_id, lightweight)
814
bzrdir.BzrDirFormat.set_default_format(old_format)
837
source.create_checkout(to_location, revision_id, lightweight)
817
840
class cmd_renames(Command):
826
849
def run(self, dir=u'.'):
827
from bzrlib.tree import find_renames
828
850
tree = WorkingTree.open_containing(dir)[0]
829
851
old_inv = tree.basis_tree().inventory
830
852
new_inv = tree.read_working_inventory()
831
renames = list(find_renames(old_inv, new_inv))
853
renames = list(_mod_tree.find_renames(old_inv, new_inv))
833
855
for old_name, new_name in renames:
834
856
self.outf.write("%s => %s\n" % (old_name, new_name))
913
939
tree, file_list = tree_files(file_list)
915
941
if file_list is None:
916
raise BzrCommandError('Specify one or more files to remove, or'
942
raise errors.BzrCommandError('Specify one or more files to'
943
' remove, or use --new.')
919
945
added = tree.changes_from(tree.basis_tree(),
920
946
specific_files=file_list).added
921
947
file_list = sorted([f[0] for f in added], reverse=True)
922
948
if len(file_list) == 0:
923
raise BzrCommandError('No matching files.')
949
raise errors.BzrCommandError('No matching files.')
924
950
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1054
1080
takes_args = ['location?']
1055
1081
takes_options = [
1082
RegistryOption('format',
1057
1083
help='Specify a format for this branch. Current'
1058
1084
' formats are: default, knit, metaweave and'
1059
1085
' weave. Default is knit; metaweave and'
1060
1086
' weave are deprecated',
1061
type=get_format_type),
1087
registry=bzrdir.format_registry,
1088
converter=get_format_type,
1089
value_switches=True),
1063
1091
def run(self, location=None, format=None):
1064
1092
if format is None:
1110
1139
(add files here)
1112
1141
takes_args = ["location"]
1113
takes_options = [Option('format',
1142
takes_options = [RegistryOption('format',
1114
1143
help='Specify a format for this repository.'
1115
1144
' Current formats are: default, knit,'
1116
1145
' metaweave and weave. Default is knit;'
1117
1146
' metaweave and weave are deprecated',
1118
type=get_format_type),
1147
registry=bzrdir.format_registry,
1148
converter=get_format_type,
1149
value_switches=True),
1119
1150
Option('trees',
1120
1151
help='Allows branches in repository to have'
1121
1152
' a working tree')]
1171
1202
# deleted files.
1173
1204
# TODO: This probably handles non-Unix newlines poorly.
1175
1206
takes_args = ['file*']
1176
takes_options = ['revision', 'diff-options', 'prefix']
1207
takes_options = ['revision', 'diff-options',
1208
Option('prefix', type=str,
1210
help='Set prefixes to added to old and new filenames, as '
1211
'two values separated by a colon.'),
1177
1213
aliases = ['di', 'dif']
1178
1214
encoding_type = 'exact'
1189
1225
elif prefix == '1':
1190
1226
old_label = 'old/'
1191
1227
new_label = 'new/'
1193
if not ':' in prefix:
1194
raise BzrError("--diff-prefix expects two values separated by a colon")
1195
1229
old_label, new_label = prefix.split(":")
1231
raise BzrCommandError(
1232
"--prefix expects two values separated by a colon")
1234
if revision and len(revision) > 2:
1235
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1236
' one or two revision specifiers')
1198
1239
tree1, file_list = internal_tree_files(file_list)
1202
except FileInWrongBranch:
1243
except errors.FileInWrongBranch:
1203
1244
if len(file_list) != 2:
1204
raise BzrCommandError("Files are in different branches")
1245
raise errors.BzrCommandError("Files are in different branches")
1206
1247
tree1, file1 = WorkingTree.open_containing(file_list[0])
1207
1248
tree2, file2 = WorkingTree.open_containing(file_list[1])
1208
1249
if file1 != "" or file2 != "":
1209
1250
# FIXME diff those two files. rbc 20051123
1210
raise BzrCommandError("Files are in different branches")
1251
raise errors.BzrCommandError("Files are in different branches")
1211
1252
file_list = None
1212
except NotBranchError:
1253
except errors.NotBranchError:
1213
1254
if (revision is not None and len(revision) == 2
1214
1255
and not revision[0].needs_branch()
1215
1256
and not revision[1].needs_branch()):
1218
1259
tree1, tree2 = None, None
1221
if revision is not None:
1222
if tree2 is not None:
1223
raise BzrCommandError("Can't specify -r with two branches")
1224
if (len(revision) == 1) or (revision[1].spec is None):
1225
return diff_cmd_helper(tree1, file_list, diff_options,
1227
old_label=old_label, new_label=new_label)
1228
elif len(revision) == 2:
1229
return diff_cmd_helper(tree1, file_list, diff_options,
1230
revision[0], revision[1],
1231
old_label=old_label, new_label=new_label)
1233
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1235
if tree2 is not None:
1236
return show_diff_trees(tree1, tree2, sys.stdout,
1237
specific_files=file_list,
1238
external_diff_options=diff_options,
1239
old_label=old_label, new_label=new_label)
1241
return diff_cmd_helper(tree1, file_list, diff_options,
1242
old_label=old_label, new_label=new_label)
1263
if tree2 is not None:
1264
if revision is not None:
1265
# FIXME: but there should be a clean way to diff between
1266
# non-default versions of two trees, it's not hard to do
1268
raise errors.BzrCommandError(
1269
"Sorry, diffing arbitrary revisions across branches "
1270
"is not implemented yet")
1271
return show_diff_trees(tree1, tree2, sys.stdout,
1272
specific_files=file_list,
1273
external_diff_options=diff_options,
1274
old_label=old_label, new_label=new_label)
1276
return diff_cmd_helper(tree1, file_list, diff_options,
1277
revision_specs=revision,
1278
old_label=old_label, new_label=new_label)
1245
1281
class cmd_deleted(Command):
1478
1523
Option('ignored', help='Print ignored files'),
1480
1525
Option('null', help='Null separate the files'),
1482
1528
@display_command
1483
1529
def run(self, revision=None, verbose=False,
1484
1530
non_recursive=False, from_root=False,
1485
1531
unknown=False, versioned=False, ignored=False,
1532
null=False, kind=None, show_ids=False, path=None):
1534
if kind and kind not in ('file', 'directory', 'symlink'):
1535
raise errors.BzrCommandError('invalid kind specified')
1488
1537
if verbose and null:
1489
raise BzrCommandError('Cannot set both --verbose and --null')
1538
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1490
1539
all = not (unknown or versioned or ignored)
1492
1541
selection = {'I':ignored, '?':unknown, 'V':versioned}
1494
tree, relpath = WorkingTree.open_containing(u'.')
1548
raise errors.BzrCommandError('cannot specify both --from-root'
1552
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1499
1558
if revision is not None:
1500
tree = tree.branch.repository.revision_tree(
1501
revision[0].in_history(tree.branch).rev_id)
1559
tree = branch.repository.revision_tree(
1560
revision[0].in_history(branch).rev_id)
1562
tree = branch.basis_tree()
1503
for fp, fc, kind, fid, entry in tree.list_files():
1564
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1504
1565
if fp.startswith(relpath):
1505
fp = fp[len(relpath):]
1566
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1506
1567
if non_recursive and '/' in fp:
1508
1569
if not all and not selection[fc]:
1571
if kind is not None and fkind != kind:
1511
1574
kindch = entry.kind_character()
1512
self.outf.write('%-8s %s%s\n' % (fc, fp, kindch))
1575
outstring = '%-8s %s%s' % (fc, fp, kindch)
1576
if show_ids and fid is not None:
1577
outstring = "%-50s %s" % (outstring, fid)
1578
self.outf.write(outstring + '\n')
1514
1580
self.outf.write(fp + '\0')
1583
self.outf.write(fid)
1584
self.outf.write('\0')
1515
1585
self.outf.flush()
1517
self.outf.write(fp + '\n')
1592
self.outf.write('%-50s %s\n' % (fp, my_id))
1594
self.outf.write(fp + '\n')
1520
1597
class cmd_unknowns(Command):
1528
1605
class cmd_ignore(Command):
1529
"""Ignore a command or pattern.
1606
"""Ignore specified files or patterns.
1531
1608
To remove patterns from the ignore list, edit the .bzrignore file.
1533
If the pattern contains a slash, it is compared to the whole path
1534
from the branch root. Otherwise, it is compared to only the last
1535
component of the path. To match a file only in the root directory,
1538
Ignore patterns are case-insensitive on case-insensitive systems.
1540
Note: wildcards must be quoted from the shell on Unix.
1610
Trailing slashes on patterns are ignored.
1611
If the pattern contains a slash or is a regular expression, it is compared
1612
to the whole path from the branch root. Otherwise, it is compared to only
1613
the last component of the path. To match a file only in the root
1614
directory, prepend './'.
1616
Ignore patterns specifying absolute paths are not allowed.
1618
Ignore patterns may include globbing wildcards such as:
1619
? - Matches any single character except '/'
1620
* - Matches 0 or more characters except '/'
1621
/**/ - Matches 0 or more directories in a path
1622
[a-z] - Matches a single character from within a group of characters
1624
Ignore patterns may also be Python regular expressions.
1625
Regular expression ignore patterns are identified by a 'RE:' prefix
1626
followed by the regular expression. Regular expression ignore patterns
1627
may not include named or numbered groups.
1629
Note: ignore patterns containing shell wildcards must be quoted from
1543
1633
bzr ignore ./Makefile
1544
1634
bzr ignore '*.class'
1635
bzr ignore 'lib/**/*.o'
1636
bzr ignore 'RE:lib/.*\.o'
1546
# TODO: Complain if the filename is absolute
1547
takes_args = ['name_pattern?']
1638
takes_args = ['name_pattern*']
1548
1639
takes_options = [
1549
1640
Option('old-default-rules',
1550
1641
help='Out the ignore rules bzr < 0.9 always used.')
1553
def run(self, name_pattern=None, old_default_rules=None):
1644
def run(self, name_pattern_list=None, old_default_rules=None):
1554
1645
from bzrlib.atomicfile import AtomicFile
1555
1646
if old_default_rules is not None:
1556
1647
# dump the rules and exit
1557
1648
for pattern in ignores.OLD_DEFAULTS:
1560
if name_pattern is None:
1561
raise BzrCommandError("ignore requires a NAME_PATTERN")
1651
if not name_pattern_list:
1652
raise errors.BzrCommandError("ignore requires at least one "
1653
"NAME_PATTERN or --old-default-rules")
1654
for name_pattern in name_pattern_list:
1655
if name_pattern[0] == '/':
1656
raise errors.BzrCommandError(
1657
"NAME_PATTERN should not be an absolute path")
1562
1658
tree, relpath = WorkingTree.open_containing(u'.')
1563
1659
ifn = tree.abspath('.bzrignore')
1564
1660
if os.path.exists(ifn):
1648
1747
tgz .tar.gz, .tgz
1651
takes_args = ['dest']
1750
takes_args = ['dest', 'branch?']
1652
1751
takes_options = ['revision', 'format', 'root']
1653
def run(self, dest, revision=None, format=None, root=None):
1752
def run(self, dest, branch=None, revision=None, format=None, root=None):
1654
1753
from bzrlib.export import export
1655
tree = WorkingTree.open_containing(u'.')[0]
1756
tree = WorkingTree.open_containing(u'.')[0]
1759
b = Branch.open(branch)
1657
1761
if revision is None:
1658
1762
# should be tree.last_revision FIXME
1659
1763
rev_id = b.last_revision()
1661
1765
if len(revision) != 1:
1662
raise BzrError('bzr export --revision takes exactly 1 argument')
1766
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1663
1767
rev_id = revision[0].in_history(b).rev_id
1664
1768
t = b.repository.revision_tree(rev_id)
1666
1770
export(t, dest, format, root)
1667
1771
except errors.NoSuchExportFormat, e:
1668
raise BzrCommandError('Unsupported export format: %s' % e.format)
1772
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1671
1775
class cmd_cat(Command):
1672
1776
"""Write a file's text from a previous revision."""
1674
takes_options = ['revision']
1778
takes_options = ['revision', 'name-from-revision']
1675
1779
takes_args = ['filename']
1780
encoding_type = 'exact'
1677
1782
@display_command
1678
def run(self, filename, revision=None):
1783
def run(self, filename, revision=None, name_from_revision=False):
1679
1784
if revision is not None and len(revision) != 1:
1680
raise BzrCommandError("bzr cat --revision takes exactly one number")
1785
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1683
1790
tree, relpath = WorkingTree.open_containing(filename)
1684
1791
b = tree.branch
1685
except NotBranchError:
1792
except (errors.NotBranchError, errors.NotLocalUrl):
1795
if revision is not None and revision[0].get_branch() is not None:
1796
b = Branch.open(revision[0].get_branch())
1688
1797
if tree is None:
1689
1798
b, relpath = Branch.open_containing(filename)
1690
if revision is not None and revision[0].get_branch() is not None:
1691
b = Branch.open(revision[0].get_branch())
1799
tree = b.basis_tree()
1692
1800
if revision is None:
1693
1801
revision_id = b.last_revision()
1695
1803
revision_id = revision[0].in_history(b).rev_id
1696
b.print_file(relpath, revision_id)
1805
cur_file_id = tree.path2id(relpath)
1806
rev_tree = b.repository.revision_tree(revision_id)
1807
old_file_id = rev_tree.path2id(relpath)
1809
if name_from_revision:
1810
if old_file_id is None:
1811
raise errors.BzrCommandError("%r is not present in revision %s"
1812
% (filename, revision_id))
1814
rev_tree.print_file(old_file_id)
1815
elif cur_file_id is not None:
1816
rev_tree.print_file(cur_file_id)
1817
elif old_file_id is not None:
1818
rev_tree.print_file(old_file_id)
1820
raise errors.BzrCommandError("%r is not present in revision %s" %
1821
(filename, revision_id))
1699
1824
class cmd_local_time_offset(Command):
1753
1879
StrictCommitFailed)
1754
1880
from bzrlib.msgeditor import edit_commit_message, \
1755
1881
make_commit_message_template
1756
from tempfile import TemporaryFile
1758
1883
# TODO: Need a blackbox test for invoking the external editor; may be
1759
1884
# slightly problematic to run this cross-platform.
1761
1886
# TODO: do more checks that the commit will succeed before
1762
1887
# spending the user's valuable time typing a commit message.
1764
# TODO: if the commit *does* happen to fail, then save the commit
1765
# message to a temporary file where it can be recovered
1766
1888
tree, selected_list = tree_files(selected_list)
1767
1889
if selected_list == ['']:
1768
1890
# workaround - commit of root of tree should be exactly the same
1773
1895
if local and not tree.branch.get_bound_location():
1774
1896
raise errors.LocalRequiresBoundBranch()
1775
if message is None and not file:
1776
template = make_commit_message_template(tree, selected_list)
1777
message = edit_commit_message(template)
1779
raise BzrCommandError("please specify a commit message"
1780
" with either --message or --file")
1781
elif message and file:
1782
raise BzrCommandError("please specify either --message or --file")
1785
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1788
raise BzrCommandError("empty commit message specified")
1898
def get_message(commit_obj):
1899
"""Callback to get commit message"""
1900
my_message = message
1901
if my_message is None and not file:
1902
template = make_commit_message_template(tree, selected_list)
1903
my_message = edit_commit_message(template)
1904
if my_message is None:
1905
raise errors.BzrCommandError("please specify a commit"
1906
" message with either --message or --file")
1907
elif my_message and file:
1908
raise errors.BzrCommandError(
1909
"please specify either --message or --file")
1911
my_message = codecs.open(file, 'rt',
1912
bzrlib.user_encoding).read()
1913
if my_message == "":
1914
raise errors.BzrCommandError("empty commit message specified")
1791
1918
reporter = ReportCommitToLog()
1793
1920
reporter = NullCommitReporter()
1796
tree.commit(message, specific_files=selected_list,
1923
tree.commit(message_callback=get_message,
1924
specific_files=selected_list,
1797
1925
allow_pointless=unchanged, strict=strict, local=local,
1798
1926
reporter=reporter)
1799
1927
except PointlessCommit:
1800
1928
# FIXME: This should really happen before the file is read in;
1801
1929
# perhaps prepare the commit; get the message; then actually commit
1802
raise BzrCommandError("no changes to commit."
1803
" use --unchanged to commit anyhow")
1930
raise errors.BzrCommandError("no changes to commit."
1931
" use --unchanged to commit anyhow")
1804
1932
except ConflictsInTree:
1805
raise BzrCommandError("Conflicts detected in working tree. "
1806
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1933
raise errors.BzrCommandError('Conflicts detected in working '
1934
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1807
1936
except StrictCommitFailed:
1808
raise BzrCommandError("Commit refused because there are unknown "
1809
"files in the working tree.")
1937
raise errors.BzrCommandError("Commit refused because there are"
1938
" unknown files in the working tree.")
1810
1939
except errors.BoundBranchOutOfDate, e:
1811
raise BzrCommandError(str(e) + "\n"
1812
'To commit to master branch, run update and then commit.\n'
1813
'You can also pass --local to commit to continue working '
1940
raise errors.BzrCommandError(str(e) + "\n"
1941
'To commit to master branch, run update and then commit.\n'
1942
'You can also pass --local to commit to continue working '
1816
1946
class cmd_check(Command):
1817
1947
"""Validate consistency of branch history.
1832
1962
check(branch, verbose)
1835
class cmd_scan_cache(Command):
1838
from bzrlib.hashcache import HashCache
1844
print '%6d stats' % c.stat_count
1845
print '%6d in hashcache' % len(c._cache)
1846
print '%6d files removed from cache' % c.removed_count
1847
print '%6d hashes updated' % c.update_count
1848
print '%6d files changed too recently to cache' % c.danger_count
1854
1965
class cmd_upgrade(Command):
1855
1966
"""Upgrade branch storage to current format.
1861
1972
takes_args = ['url?']
1862
1973
takes_options = [
1864
help='Upgrade to a specific format. Current formats'
1865
' are: default, knit, metaweave and weave.'
1866
' Default is knit; metaweave and weave are'
1868
type=get_format_type),
1974
RegistryOption('format',
1975
help='Upgrade to a specific format. Current formats'
1976
' are: default, knit, metaweave and weave.'
1977
' Default is knit; metaweave and weave are'
1979
registry=bzrdir.format_registry,
1980
converter=get_format_type,
1981
value_switches=True),
1943
2056
class cmd_selftest(Command):
1944
2057
"""Run internal test suite.
1946
This creates temporary test directories in the working directory,
1947
but not existing data is affected. These directories are deleted
1948
if the tests pass, or left behind to help in debugging if they
1949
fail and --keep-output is specified.
2059
This creates temporary test directories in the working directory, but not
2060
existing data is affected. These directories are deleted if the tests
2061
pass, or left behind to help in debugging if they fail and --keep-output
1951
If arguments are given, they are regular expressions that say
1952
which tests should run.
2064
If arguments are given, they are regular expressions that say which tests
2065
should run. Tests matching any expression are run, and other tests are
2068
Alternatively if --first is given, matching tests are run first and then
2069
all other tests are run. This is useful if you have been working in a
2070
particular area, but want to make sure nothing else was broken.
1954
2072
If the global option '--no-plugins' is given, plugins are not loaded
1955
2073
before running the selftests. This has two effects: features provided or
1956
2074
modified by plugins will not be tested, and tests provided by plugins will
1960
2078
bzr selftest ignore
2079
run only tests relating to 'ignore'
1961
2080
bzr --no-plugins selftest -v
2081
disable plugins and list tests as they're run
1963
2083
# TODO: --list should give a list of all available tests
1996
2116
Option('cache-dir', type=str,
1997
2117
help='a directory to cache intermediate'
1998
2118
' benchmark steps'),
2119
Option('clean-output',
2120
help='clean temporary tests directories'
2121
' without running tests'),
2123
help='run all tests, but run specified tests first',
2126
encoding_type = 'replace'
2001
2128
def run(self, testspecs_list=None, verbose=None, one=False,
2002
2129
keep_output=False, transport=None, benchmark=None,
2003
lsprof_timed=None, cache_dir=None):
2130
lsprof_timed=None, cache_dir=None, clean_output=False,
2004
2132
import bzrlib.ui
2005
2133
from bzrlib.tests import selftest
2006
2134
import bzrlib.benchmarks as benchmarks
2007
2135
from bzrlib.benchmarks import tree_creator
2138
from bzrlib.tests import clean_selftest_output
2139
clean_selftest_output()
2009
2142
if cache_dir is not None:
2010
2143
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2011
# we don't want progress meters from the tests to go to the
2012
# real output; and we don't want log messages cluttering up
2014
save_ui = ui.ui_factory
2015
2144
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2016
2145
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2018
info('running tests...')
2147
if testspecs_list is not None:
2148
pattern = '|'.join(testspecs_list)
2152
test_suite_factory = benchmarks.test_suite
2155
# TODO: should possibly lock the history file...
2156
benchfile = open(".perf_history", "at", buffering=1)
2158
test_suite_factory = None
2020
ui.ui_factory = ui.SilentUIFactory()
2021
if testspecs_list is not None:
2022
pattern = '|'.join(testspecs_list)
2026
test_suite_factory = benchmarks.test_suite
2029
# TODO: should possibly lock the history file...
2030
benchfile = open(".perf_history", "at")
2032
test_suite_factory = None
2037
result = selftest(verbose=verbose,
2039
stop_on_failure=one,
2040
keep_output=keep_output,
2041
transport=transport,
2042
test_suite_factory=test_suite_factory,
2043
lsprof_timed=lsprof_timed,
2044
bench_history=benchfile)
2046
if benchfile is not None:
2049
info('tests passed')
2051
info('tests failed')
2052
return int(not result)
2163
result = selftest(verbose=verbose,
2165
stop_on_failure=one,
2166
keep_output=keep_output,
2167
transport=transport,
2168
test_suite_factory=test_suite_factory,
2169
lsprof_timed=lsprof_timed,
2170
bench_history=benchfile,
2171
matching_tests_first=first,
2054
ui.ui_factory = save_ui
2174
if benchfile is not None:
2177
info('tests passed')
2179
info('tests failed')
2180
return int(not result)
2057
2183
class cmd_version(Command):
2145
2271
takes_args = ['branch?']
2146
2272
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2147
2273
Option('show-base', help="Show base revision text in "
2149
2275
Option('uncommitted', help='Apply uncommitted changes'
2150
' from a working copy, instead of branch changes')]
2276
' from a working copy, instead of branch changes'),
2277
Option('pull', help='If the destination is already'
2278
' completely merged into the source, pull from the'
2279
' source rather than merging. When this happens,'
2280
' you do not need to commit the result.'),
2152
2283
def help(self):
2153
from merge import merge_type_help
2154
2284
from inspect import getdoc
2155
return getdoc(self) + '\n' + merge_type_help()
2285
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2157
2287
def run(self, branch=None, revision=None, force=False, merge_type=None,
2158
2288
show_base=False, reprocess=False, remember=False,
2289
uncommitted=False, pull=False):
2160
2290
if merge_type is None:
2161
merge_type = Merge3Merger
2291
merge_type = _mod_merge.Merge3Merger
2163
2293
tree = WorkingTree.open_containing(u'.')[0]
2165
2295
if branch is not None:
2167
2297
reader = bundle.read_bundle_from_url(branch)
2298
except errors.NotABundle:
2169
2299
pass # Continue on considering this url a Branch
2171
2301
conflicts = merge_bundle(reader, tree, not force, merge_type,
2222
2352
pb = ui.ui_factory.nested_progress_bar()
2225
conflict_count = merge(other, base, check_clean=(not force),
2226
merge_type=merge_type,
2227
reprocess=reprocess,
2228
show_base=show_base,
2229
pb=pb, file_list=interesting_files)
2355
conflict_count = _merge_helper(
2356
other, base, check_clean=(not force),
2357
merge_type=merge_type,
2358
reprocess=reprocess,
2359
show_base=show_base,
2361
pb=pb, file_list=interesting_files)
2232
2364
if conflict_count != 0:
2288
2420
def help(self):
2289
from merge import merge_type_help
2290
2421
from inspect import getdoc
2291
return getdoc(self) + '\n' + merge_type_help()
2422
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2293
2424
def run(self, file_list=None, merge_type=None, show_base=False,
2294
2425
reprocess=False):
2295
from bzrlib.merge import merge_inner, transform_tree
2296
2426
if merge_type is None:
2297
merge_type = Merge3Merger
2427
merge_type = _mod_merge.Merge3Merger
2298
2428
tree, file_list = tree_files(file_list)
2299
2429
tree.lock_write()
2301
2431
parents = tree.get_parent_ids()
2302
2432
if len(parents) != 2:
2303
raise BzrCommandError("Sorry, remerge only works after normal"
2304
" merges. Not cherrypicking or"
2433
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2434
" merges. Not cherrypicking or"
2306
2436
repository = tree.branch.repository
2307
2437
base_revision = common_ancestor(parents[0],
2308
2438
parents[1], repository)
2324
2454
for name, ie in tree.inventory.iter_entries(file_id):
2325
2455
interesting_ids.add(ie.file_id)
2326
2456
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2327
transform_tree(tree, tree.basis_tree(), interesting_ids)
2458
# Remerge only supports resolving contents conflicts
2459
allowed_conflicts = ('text conflict', 'contents conflict')
2460
restore_files = [c.path for c in conflicts
2461
if c.typestring in allowed_conflicts]
2462
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2328
2463
tree.set_conflicts(ConflictList(new_conflicts))
2329
if file_list is None:
2330
restore_files = list(tree.iter_conflicts())
2464
if file_list is not None:
2332
2465
restore_files = file_list
2333
2466
for filename in restore_files:
2335
2468
restore(tree.abspath(filename))
2336
except NotConflicted:
2469
except errors.NotConflicted:
2338
conflicts = merge_inner(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)
2471
conflicts = _mod_merge.merge_inner(
2472
tree.branch, other_tree, base_tree,
2474
interesting_ids=interesting_ids,
2475
other_rev_id=parents[1],
2476
merge_type=merge_type,
2477
show_base=show_base,
2478
reprocess=reprocess)
2347
2481
if conflicts > 0:
2402
2536
class cmd_assert_fail(Command):
2403
2537
"""Test reporting of assertion failures"""
2538
# intended just for use in testing
2406
assert False, "always fails"
2543
raise AssertionError("always fails")
2409
2546
class cmd_help(Command):
2410
2547
"""Show help on a command or other topic.
2412
For a list of all available commands, say 'bzr help commands'."""
2549
For a list of all available commands, say 'bzr help commands'.
2413
2551
takes_options = [Option('long', 'show help on all commands')]
2414
2552
takes_args = ['topic?']
2415
2553
aliases = ['?', '--help', '-?', '-h']
2417
2555
@display_command
2418
2556
def run(self, topic=None, long=False):
2420
2558
if topic is None and long:
2421
2559
topic = "commands"
2560
bzrlib.help.help(topic)
2425
2563
class cmd_shell_complete(Command):
2426
2564
"""Show appropriate completions for context.
2428
For a list of all available commands, say 'bzr shell-complete'."""
2566
For a list of all available commands, say 'bzr shell-complete'.
2429
2568
takes_args = ['context?']
2430
2569
aliases = ['s-c']
2601
2742
takes_args = ['filename']
2602
2743
takes_options = [Option('all', help='show annotations on all lines'),
2603
2744
Option('long', help='show date in annotations'),
2607
2749
@display_command
2608
def run(self, filename, all=False, long=False, revision=None):
2750
def run(self, filename, all=False, long=False, revision=None,
2609
2752
from bzrlib.annotate import annotate_file
2610
2753
tree, relpath = WorkingTree.open_containing(filename)
2611
2754
branch = tree.branch
2614
2757
if revision is None:
2615
2758
revision_id = branch.last_revision()
2616
2759
elif len(revision) != 1:
2617
raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2760
raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2619
2762
revision_id = revision[0].in_history(branch).rev_id
2620
2763
file_id = tree.inventory.path2id(relpath)
2621
2764
tree = branch.repository.revision_tree(revision_id)
2622
2765
file_version = tree.inventory[file_id].revision
2623
annotate_file(branch, file_version, file_id, long, all, sys.stdout)
2766
annotate_file(branch, file_version, file_id, long, all, sys.stdout,
2625
2769
branch.unlock()
2636
2780
def run(self, revision_id_list=None, revision=None):
2637
2781
import bzrlib.gpg as gpg
2638
2782
if revision_id_list is not None and revision is not None:
2639
raise BzrCommandError('You can only supply one of revision_id or --revision')
2783
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
2640
2784
if revision_id_list is None and revision is None:
2641
raise BzrCommandError('You must supply either --revision or a revision_id')
2785
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
2642
2786
b = WorkingTree.open_containing(u'.')[0].branch
2643
2787
gpg_strategy = gpg.GPGStrategy(b.get_config())
2644
2788
if revision_id_list is not None:
2657
2801
if to_revid is None:
2658
2802
to_revno = b.revno()
2659
2803
if from_revno is None or to_revno is None:
2660
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
2804
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2661
2805
for revno in range(from_revno, to_revno + 1):
2662
2806
b.repository.sign_revision(b.get_rev_id(revno),
2665
raise BzrCommandError('Please supply either one revision, or a range.')
2809
raise errors.BzrCommandError('Please supply either one revision, or a range.')
2668
2812
class cmd_bind(Command):
2863
3007
print 'listening on port: ', server.port
2864
3008
sys.stdout.flush()
2866
raise BzrCommandError("bzr serve requires one of --inet or --port")
3010
raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
2870
3014
# command-line interpretation helper for merge-related commands
2871
def merge(other_revision, base_revision,
2872
check_clean=True, ignore_zero=False,
2873
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2874
file_list=None, show_base=False, reprocess=False,
2875
pb=DummyProgress()):
3015
def _merge_helper(other_revision, base_revision,
3016
check_clean=True, ignore_zero=False,
3017
this_dir=None, backup_files=False,
3019
file_list=None, show_base=False, reprocess=False,
3021
pb=DummyProgress()):
2876
3022
"""Merge changes into a tree.
2900
3046
clients might prefer to call merge.merge_inner(), which has less magic
2903
from bzrlib.merge import Merger
3049
# Loading it late, so that we don't always have to import bzrlib.merge
3050
if merge_type is None:
3051
merge_type = _mod_merge.Merge3Merger
2904
3052
if this_dir is None:
2905
3053
this_dir = u'.'
2906
3054
this_tree = WorkingTree.open_containing(this_dir)[0]
2907
if show_base and not merge_type is Merge3Merger:
2908
raise BzrCommandError("Show-base is not supported for this merge"
2909
" type. %s" % merge_type)
3055
if show_base and not merge_type is _mod_merge.Merge3Merger:
3056
raise errors.BzrCommandError("Show-base is not supported for this merge"
3057
" type. %s" % merge_type)
2910
3058
if reprocess and not merge_type.supports_reprocess:
2911
raise BzrCommandError("Conflict reduction is not supported for merge"
2912
" type %s." % merge_type)
3059
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3060
" type %s." % merge_type)
2913
3061
if reprocess and show_base:
2914
raise BzrCommandError("Cannot do conflict reduction and show base.")
3062
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
2916
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
3064
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
2917
3066
merger.pp = ProgressPhase("Merge phase", 5, pb)
2918
3067
merger.pp.next_phase()
2919
3068
merger.check_basis(check_clean)
2923
3072
if merger.base_rev_id == merger.other_rev_id:
2924
3073
note('Nothing to do.')
3075
if file_list is None:
3076
if pull and merger.base_rev_id == merger.this_rev_id:
3077
count = merger.this_tree.pull(merger.this_branch,
3078
False, merger.other_rev_id)
3079
note('%d revision(s) pulled.' % (count,))
2926
3081
merger.backup_files = backup_files
2927
3082
merger.merge_type = merge_type
2928
3083
merger.set_interesting_files(file_list)