1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
1
# Copyright (C) 2004, 2005, 2006 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
41
from bzrlib.branch import Branch, BranchReferenceFormat
42
from bzrlib.bundle import read_bundle_from_url
44
from bzrlib.branch import Branch
43
45
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
44
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
45
52
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
53
from bzrlib.option import Option
52
54
from bzrlib.progress import DummyProgress, ProgressPhase
53
from bzrlib.revision import common_ancestor
54
from bzrlib.revisionspec import RevisionSpec
55
55
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
58
def tree_files(file_list, default_branch=u'.'):
63
60
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]))
61
except errors.FileInWrongBranch, e:
62
raise errors.BzrCommandError("%s is not in the same branch as %s" %
63
(e.path, file_list[0]))
69
66
# XXX: Bad function name; should possibly also be a class method of
79
76
:param file_list: Filenames to convert.
81
:param default_branch: Fallback tree path to use if file_list is empty or None.
78
:param default_branch: Fallback tree path to use if file_list is empty or
83
81
:return: workingtree, [relative_paths]
85
83
if file_list is None or len(file_list) == 0:
86
84
return WorkingTree.open_containing(default_branch)[0], file_list
87
tree = WorkingTree.open_containing(file_list[0])[0]
85
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
89
87
for filename in file_list:
91
new_list.append(tree.relpath(filename))
89
new_list.append(tree.relpath(osutils.dereference_path(filename)))
92
90
except errors.PathNotChild:
93
raise FileInWrongBranch(tree.branch, filename)
91
raise errors.FileInWrongBranch(tree.branch, filename)
94
92
return tree, new_list
115
113
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
116
114
"metaweave and weave" % typestring
117
raise BzrCommandError(msg)
115
raise errors.BzrCommandError(msg)
120
118
# TODO: Make sure no commands unconditionally use the working directory as a
195
193
def run(self, revision_id=None, revision=None):
197
195
if revision_id is not None and revision is not None:
198
raise BzrCommandError('You can only supply one of revision_id or --revision')
196
raise errors.BzrCommandError('You can only supply one of'
197
' revision_id or --revision')
199
198
if revision_id is None and revision is None:
200
raise BzrCommandError('You must supply either --revision or a revision_id')
199
raise errors.BzrCommandError('You must supply either'
200
' --revision or a revision_id')
201
201
b = WorkingTree.open_containing(u'.')[0].branch
203
203
# TODO: jam 20060112 should cat-revision always output utf-8?
206
206
elif revision is not None:
207
207
for rev in revision:
209
raise BzrCommandError('You cannot specify a NULL revision.')
209
raise errors.BzrCommandError('You cannot specify a NULL'
210
211
revno, rev_id = rev.in_history(b)
211
212
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
242
243
for rev in revision_info_list:
243
244
revs.append(RevisionSpec.from_string(rev))
244
245
if len(revs) == 0:
245
raise BzrCommandError('You must supply a revision identifier')
246
raise errors.BzrCommandError('You must supply a revision identifier')
247
248
b = WorkingTree.open_containing(u'.')[0].branch
299
300
base_tree, base_path = WorkingTree.open_containing(
301
302
except errors.NoWorkingTree:
302
base_branch, base_path = branch.Branch.open_containing(
303
base_branch, base_path = Branch.open_containing(
304
305
base_tree = base_branch.basis_tree()
375
376
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
376
377
if kind and kind not in ['file', 'directory', 'symlink']:
377
raise BzrCommandError('invalid kind specified')
378
raise errors.BzrCommandError('invalid kind specified')
379
380
work_tree, file_list = tree_files(file_list)
381
382
if revision is not None:
382
383
if len(revision) > 1:
383
raise BzrCommandError('bzr inventory --revision takes'
384
' exactly one revision identifier')
384
raise errors.BzrCommandError('bzr inventory --revision takes'
385
' exactly one revision identifier')
385
386
revision_id = revision[0].in_history(work_tree.branch).rev_id
386
387
tree = work_tree.branch.repository.revision_tree(revision_id)
397
398
if file_list is not None:
398
file_ids = bzrlib.tree.find_ids_across_trees(file_list, trees,
399
file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
399
400
require_versioned=True)
400
401
# find_ids_across_trees may include some paths that don't
401
402
# exist in 'tree'.
439
440
if len(names_list) < 2:
440
raise BzrCommandError("missing file argument")
441
raise errors.BzrCommandError("missing file argument")
441
442
tree, rel_names = tree_files(names_list)
443
444
if os.path.isdir(names_list[-1]):
446
447
self.outf.write("%s => %s\n" % pair)
448
449
if len(names_list) != 2:
449
raise BzrCommandError('to mv multiple files the destination '
450
'must be a versioned directory')
450
raise errors.BzrCommandError('to mv multiple files the destination '
451
'must be a versioned directory')
451
452
tree.rename_one(rel_names[0], rel_names[1])
452
453
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
489
490
if location is not None:
491
492
reader = bundle.read_bundle_from_url(location)
493
except errors.NotABundle:
493
494
pass # Continue on considering this url a Branch
495
496
stored_loc = branch_to.get_parent()
496
497
if location is None:
497
498
if stored_loc is None:
498
raise BzrCommandError("No pull location known or specified.")
499
raise errors.BzrCommandError("No pull location known or"
500
502
display_url = urlutils.unescape_for_display(stored_loc,
501
503
self.outf.encoding)
579
581
stored_loc = br_from.get_push_location()
580
582
if location is None:
581
583
if stored_loc is None:
582
raise BzrCommandError("No push location known or specified.")
584
raise errors.BzrCommandError("No push location known or specified.")
584
586
display_url = urlutils.unescape_for_display(stored_loc,
585
587
self.outf.encoding)
601
603
relurl = to_transport.relpath(location_url)
602
604
mutter('creating directory %s => %s', location_url, relurl)
603
605
to_transport.mkdir(relurl)
605
raise BzrCommandError("Parent directory of %s "
606
"does not exist." % location)
606
except errors.NoSuchFile:
607
raise errors.BzrCommandError("Parent directory of %s "
608
"does not exist." % location)
608
610
current = to_transport.base
609
611
needed = [(to_transport, to_transport.relpath(location_url))]
612
614
to_transport, relpath = needed[-1]
613
615
to_transport.mkdir(relpath)
617
except errors.NoSuchFile:
616
618
new_transport = to_transport.clone('..')
617
619
needed.append((new_transport,
618
620
new_transport.relpath(to_transport.base)))
619
621
if new_transport.base == to_transport.base:
620
raise BzrCommandError("Could not create "
622
raise errors.BzrCommandError("Could not create "
622
624
dir_to = br_from.bzrdir.clone(location_url,
623
625
revision_id=br_from.last_revision())
624
626
br_to = dir_to.open_branch()
639
641
warning('This transport does not update the working '
640
642
'tree of: %s' % (br_to.base,))
641
643
count = br_to.pull(br_from, overwrite)
642
except NoWorkingTree:
644
except errors.NoWorkingTree:
643
645
count = br_to.pull(br_from, overwrite)
645
647
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.")
648
except errors.DivergedBranches:
649
raise errors.BzrCommandError('These branches have diverged.'
650
' Try using "merge" and then "push".')
649
651
note('%d revision(s) pushed.' % (count,))
678
680
if revision is None:
679
681
revision = [None]
680
682
elif len(revision) > 1:
681
raise BzrCommandError(
683
raise errors.BzrCommandError(
682
684
'bzr branch --revision takes exactly 1 revision value')
684
686
br_from = Branch.open(from_location)
685
687
except OSError, e:
686
688
if e.errno == errno.ENOENT:
687
raise BzrCommandError('Source location "%s" does not'
688
' exist.' % to_location)
689
raise errors.BzrCommandError('Source location "%s" does not'
690
' exist.' % to_location)
691
693
br_from.lock_read()
712
714
to_transport.mkdir('.')
713
715
except errors.FileExists:
714
raise BzrCommandError('Target directory "%s" already'
715
' exists.' % to_location)
716
raise errors.BzrCommandError('Target directory "%s" already'
717
' exists.' % to_location)
716
718
except errors.NoSuchFile:
717
raise BzrCommandError('Parent of "%s" does not exist.' %
719
raise errors.BzrCommandError('Parent of "%s" does not exist.'
720
722
# preserve whatever source format we have.
721
723
dir = br_from.bzrdir.sprout(to_transport.base,
724
726
except errors.NoSuchRevision:
725
727
to_transport.delete_tree('.')
726
728
msg = "The branch %s has no revision %s." % (from_location, revision[0])
727
raise BzrCommandError(msg)
729
raise errors.BzrCommandError(msg)
728
730
except errors.UnlistableBranch:
729
731
osutils.rmtree(to_location)
730
732
msg = "The branch %s cannot be used as a --basis" % (basis,)
731
raise BzrCommandError(msg)
733
raise errors.BzrCommandError(msg)
733
735
branch.control_files.put_utf8('branch-name', name)
734
736
note('Branched %d revision(s).' % branch.revno())
799
801
os.mkdir(to_location)
800
802
except OSError, e:
801
803
if e.errno == errno.EEXIST:
802
raise BzrCommandError('Target directory "%s" already'
803
' exists.' % to_location)
804
raise errors.BzrCommandError('Target directory "%s" already'
805
' exists.' % to_location)
804
806
if e.errno == errno.ENOENT:
805
raise BzrCommandError('Parent of "%s" does not exist.' %
807
raise errors.BzrCommandError('Parent of "%s" does not exist.'
809
811
old_format = bzrdir.BzrDirFormat.get_default_format()
826
828
def run(self, dir=u'.'):
827
from bzrlib.tree import find_renames
828
829
tree = WorkingTree.open_containing(dir)[0]
829
830
old_inv = tree.basis_tree().inventory
830
831
new_inv = tree.read_working_inventory()
831
renames = list(find_renames(old_inv, new_inv))
832
renames = list(_mod_tree.find_renames(old_inv, new_inv))
833
834
for old_name, new_name in renames:
834
835
self.outf.write("%s => %s\n" % (old_name, new_name))
913
918
tree, file_list = tree_files(file_list)
915
920
if file_list is None:
916
raise BzrCommandError('Specify one or more files to remove, or'
921
raise errors.BzrCommandError('Specify one or more files to'
922
' remove, or use --new.')
919
924
added = tree.changes_from(tree.basis_tree(),
920
925
specific_files=file_list).added
921
926
file_list = sorted([f[0] for f in added], reverse=True)
922
927
if len(file_list) == 0:
923
raise BzrCommandError('No matching files.')
928
raise errors.BzrCommandError('No matching files.')
924
929
tree.remove(file_list, verbose=verbose, to_file=self.outf)
940
945
tree, relpath = WorkingTree.open_containing(filename)
941
946
i = tree.inventory.path2id(relpath)
943
raise BzrError("%r is not a versioned file" % filename)
948
raise errors.BzrError("%r is not a versioned file" % filename)
945
950
self.outf.write(i + '\n')
961
966
inv = tree.inventory
962
967
fid = inv.path2id(relpath)
964
raise BzrError("%r is not a versioned file" % filename)
969
raise errors.BzrError("%r is not a versioned file" % filename)
965
970
for fip in inv.get_idpath(fid):
966
971
self.outf.write(fip + '\n')
1083
1088
existing_bzrdir = bzrdir.BzrDir.open(location)
1084
except NotBranchError:
1089
except errors.NotBranchError:
1085
1090
# really a NotBzrDir error...
1086
1091
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1093
from bzrlib.transport.local import LocalTransport
1088
1094
if existing_bzrdir.has_branch():
1089
1095
if (isinstance(to_transport, LocalTransport)
1090
1096
and not existing_bzrdir.has_workingtree()):
1202
except FileInWrongBranch:
1209
except errors.FileInWrongBranch:
1203
1210
if len(file_list) != 2:
1204
raise BzrCommandError("Files are in different branches")
1211
raise errors.BzrCommandError("Files are in different branches")
1206
1213
tree1, file1 = WorkingTree.open_containing(file_list[0])
1207
1214
tree2, file2 = WorkingTree.open_containing(file_list[1])
1208
1215
if file1 != "" or file2 != "":
1209
1216
# FIXME diff those two files. rbc 20051123
1210
raise BzrCommandError("Files are in different branches")
1217
raise errors.BzrCommandError("Files are in different branches")
1211
1218
file_list = None
1212
except NotBranchError:
1219
except errors.NotBranchError:
1213
1220
if (revision is not None and len(revision) == 2
1214
1221
and not revision[0].needs_branch()
1215
1222
and not revision[1].needs_branch()):
1221
1228
if revision is not None:
1222
1229
if tree2 is not None:
1223
raise BzrCommandError("Can't specify -r with two branches")
1230
raise errors.BzrCommandError("Can't specify -r with two branches")
1224
1231
if (len(revision) == 1) or (revision[1].spec is None):
1225
1232
return diff_cmd_helper(tree1, file_list, diff_options,
1230
1237
revision[0], revision[1],
1231
1238
old_label=old_label, new_label=new_label)
1233
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1240
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1241
' one or two revision identifiers')
1235
1243
if tree2 is not None:
1236
1244
return show_diff_trees(tree1, tree2, sys.stdout,
1371
1381
# either no tree, or is remote.
1372
1382
inv = b.basis_tree().inventory
1373
1383
file_id = inv.path2id(fp)
1385
raise errors.BzrCommandError(
1386
"Path does not have any revision history: %s" %
1375
1389
# local dir only
1376
1390
# FIXME ? log the current subdir only RBC 20060203
1392
1406
# b is taken from revision[0].get_branch(), and
1393
1407
# show_log will use its revision_history. Having
1394
1408
# different branches will lead to weird behaviors.
1395
raise BzrCommandError(
1409
raise errors.BzrCommandError(
1396
1410
"Log doesn't accept two revisions in different branches.")
1397
1411
if revision[0].spec is None:
1398
1412
# missing begin-range means first revision
1407
1421
rev2 = revision[1].in_history(b).revno
1409
raise BzrCommandError('bzr log --revision takes one or two values.')
1423
raise errors.BzrCommandError('bzr log --revision takes one or two values.')
1411
1425
# By this point, the revision numbers are converted to the +ve
1412
1426
# form if they were supplied in the -ve form, so we can do
1488
1502
if verbose and null:
1489
raise BzrCommandError('Cannot set both --verbose and --null')
1503
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1490
1504
all = not (unknown or versioned or ignored)
1492
1506
selection = {'I':ignored, '?':unknown, 'V':versioned}
1500
1514
tree = tree.branch.repository.revision_tree(
1501
1515
revision[0].in_history(tree.branch).rev_id)
1503
for fp, fc, kind, fid, entry in tree.list_files():
1517
for fp, fc, kind, fid, entry in tree.list_files(include_root=False):
1504
1518
if fp.startswith(relpath):
1505
1519
fp = fp[len(relpath):]
1506
1520
if non_recursive and '/' in fp:
1560
1574
if name_pattern is None:
1561
raise BzrCommandError("ignore requires a NAME_PATTERN")
1575
raise errors.BzrCommandError("ignore requires a NAME_PATTERN")
1562
1576
tree, relpath = WorkingTree.open_containing(u'.')
1563
1577
ifn = tree.abspath('.bzrignore')
1564
1578
if os.path.exists(ifn):
1659
1673
rev_id = b.last_revision()
1661
1675
if len(revision) != 1:
1662
raise BzrError('bzr export --revision takes exactly 1 argument')
1676
raise errors.BzrError('bzr export --revision takes exactly'
1663
1678
rev_id = revision[0].in_history(b).rev_id
1664
1679
t = b.repository.revision_tree(rev_id)
1666
1681
export(t, dest, format, root)
1667
1682
except errors.NoSuchExportFormat, e:
1668
raise BzrCommandError('Unsupported export format: %s' % e.format)
1683
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1671
1686
class cmd_cat(Command):
1677
1692
@display_command
1678
1693
def run(self, filename, revision=None):
1679
1694
if revision is not None and len(revision) != 1:
1680
raise BzrCommandError("bzr cat --revision takes exactly one number")
1695
raise errors.BzrCommandError("bzr cat --revision takes exactly one number")
1683
1698
tree, relpath = WorkingTree.open_containing(filename)
1684
1699
b = tree.branch
1685
except NotBranchError:
1700
except errors.NotBranchError:
1688
1703
if tree is None:
1776
1791
template = make_commit_message_template(tree, selected_list)
1777
1792
message = edit_commit_message(template)
1778
1793
if message is None:
1779
raise BzrCommandError("please specify a commit message"
1780
" with either --message or --file")
1794
raise errors.BzrCommandError("please specify a commit message"
1795
" with either --message or --file")
1781
1796
elif message and file:
1782
raise BzrCommandError("please specify either --message or --file")
1797
raise errors.BzrCommandError("please specify either --message or --file")
1785
1800
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1787
1802
if message == "":
1788
raise BzrCommandError("empty commit message specified")
1803
raise errors.BzrCommandError("empty commit message specified")
1791
1806
reporter = ReportCommitToLog()
1799
1814
except PointlessCommit:
1800
1815
# FIXME: This should really happen before the file is read in;
1801
1816
# perhaps prepare the commit; get the message; then actually commit
1802
raise BzrCommandError("no changes to commit."
1803
" use --unchanged to commit anyhow")
1817
raise errors.BzrCommandError("no changes to commit."
1818
" use --unchanged to commit anyhow")
1804
1819
except ConflictsInTree:
1805
raise BzrCommandError("Conflicts detected in working tree. "
1820
raise errors.BzrCommandError("Conflicts detected in working tree. "
1806
1821
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1807
1822
except StrictCommitFailed:
1808
raise BzrCommandError("Commit refused because there are unknown "
1809
"files in the working tree.")
1823
raise errors.BzrCommandError("Commit refused because there are unknown "
1824
"files in the working tree.")
1810
1825
except errors.BoundBranchOutOfDate, e:
1811
raise BzrCommandError(str(e) + "\n"
1826
raise errors.BzrCommandError(str(e) + "\n"
1812
1827
'To commit to master branch, run update and then commit.\n'
1813
1828
'You can also pass --local to commit to continue working '
1814
1829
'disconnected.')
1898
1913
# use branch if we're inside one; otherwise global config
1900
1915
c = Branch.open_containing('.')[0].get_config()
1901
except NotBranchError:
1916
except errors.NotBranchError:
1902
1917
c = config.GlobalConfig()
1904
1919
self.outf.write(c.user_email() + '\n')
1909
1924
# display a warning if an email address isn't included in the given name.
1911
1926
config.extract_email_address(name)
1927
except errors.NoEmailInUsername, e:
1913
1928
warning('"%s" does not seem to contain an email address. '
1914
1929
'This is allowed, but not recommended.', name)
2083
2098
@display_command
2084
2099
def run(self, branch, other):
2085
from bzrlib.revision import common_ancestor, MultipleRevisionSources
2100
from bzrlib.revision import MultipleRevisionSources
2087
2102
branch1 = Branch.open_containing(branch)[0]
2088
2103
branch2 = Branch.open_containing(other)[0]
2150
2165
' from a working copy, instead of branch changes')]
2152
2167
def help(self):
2153
from merge import merge_type_help
2154
2168
from inspect import getdoc
2155
return getdoc(self) + '\n' + merge_type_help()
2169
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2157
2171
def run(self, branch=None, revision=None, force=False, merge_type=None,
2158
2172
show_base=False, reprocess=False, remember=False,
2159
2173
uncommitted=False):
2160
2174
if merge_type is None:
2161
merge_type = Merge3Merger
2175
merge_type = _mod_merge.Merge3Merger
2163
2177
tree = WorkingTree.open_containing(u'.')[0]
2165
2179
if branch is not None:
2167
2181
reader = bundle.read_bundle_from_url(branch)
2182
except errors.NotABundle:
2169
2183
pass # Continue on considering this url a Branch
2171
2185
conflicts = merge_bundle(reader, tree, not force, merge_type,
2189
2203
other_branch, path = Branch.open_containing(branch)
2191
2205
if uncommitted:
2192
raise BzrCommandError('Cannot use --uncommitted and --revision'
2193
' at the same time.')
2206
raise errors.BzrCommandError('Cannot use --uncommitted and'
2207
' --revision at the same time.')
2194
2208
branch = revision[0].get_branch() or branch
2195
2209
if len(revision) == 1:
2196
2210
base = [None, None]
2201
2215
assert len(revision) == 2
2202
2216
if None in revision:
2203
raise BzrCommandError(
2217
raise errors.BzrCommandError(
2204
2218
"Merge doesn't permit empty revision specifier.")
2205
2219
base_branch, path = Branch.open_containing(branch)
2206
2220
branch1 = revision[1].get_branch() or branch
2222
2236
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)
2239
conflict_count = _merge_helper(
2240
other, base, check_clean=(not force),
2241
merge_type=merge_type,
2242
reprocess=reprocess,
2243
show_base=show_base,
2244
pb=pb, file_list=interesting_files)
2232
2247
if conflict_count != 0:
2253
2268
stored_location = tree.branch.get_parent()
2254
2269
mutter("%s", stored_location)
2255
2270
if stored_location is None:
2256
raise BzrCommandError("No location specified or remembered")
2271
raise errors.BzrCommandError("No location specified or remembered")
2257
2272
display_url = urlutils.unescape_for_display(stored_location, self.outf.encoding)
2258
2273
self.outf.write("%s remembered location %s\n" % (verb_string, display_url))
2259
2274
return stored_location
2288
2303
def help(self):
2289
from merge import merge_type_help
2290
2304
from inspect import getdoc
2291
return getdoc(self) + '\n' + merge_type_help()
2305
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2293
2307
def run(self, file_list=None, merge_type=None, show_base=False,
2294
2308
reprocess=False):
2295
from bzrlib.merge import merge_inner, transform_tree
2296
2309
if merge_type is None:
2297
merge_type = Merge3Merger
2310
merge_type = _mod_merge.Merge3Merger
2298
2311
tree, file_list = tree_files(file_list)
2299
2312
tree.lock_write()
2301
2314
parents = tree.get_parent_ids()
2302
2315
if len(parents) != 2:
2303
raise BzrCommandError("Sorry, remerge only works after normal"
2304
" merges. Not cherrypicking or"
2316
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2317
" merges. Not cherrypicking or"
2306
2319
repository = tree.branch.repository
2307
2320
base_revision = common_ancestor(parents[0],
2308
2321
parents[1], repository)
2316
2329
for filename in file_list:
2317
2330
file_id = tree.path2id(filename)
2318
2331
if file_id is None:
2319
raise NotVersionedError(filename)
2332
raise errors.NotVersionedError(filename)
2320
2333
interesting_ids.add(file_id)
2321
2334
if tree.kind(file_id) != "directory":
2324
2337
for name, ie in tree.inventory.iter_entries(file_id):
2325
2338
interesting_ids.add(ie.file_id)
2326
2339
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2327
transform_tree(tree, tree.basis_tree(), interesting_ids)
2341
# Remerge only supports resolving contents conflicts
2342
allowed_conflicts = ('text conflict', 'contents conflict')
2343
restore_files = [c.path for c in conflicts
2344
if c.typestring in allowed_conflicts]
2345
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2328
2346
tree.set_conflicts(ConflictList(new_conflicts))
2329
if file_list is None:
2330
restore_files = list(tree.iter_conflicts())
2347
if file_list is not None:
2332
2348
restore_files = file_list
2333
2349
for filename in restore_files:
2335
2351
restore(tree.abspath(filename))
2336
except NotConflicted:
2352
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)
2354
conflicts = _mod_merge.merge_inner(
2355
tree.branch, other_tree, base_tree,
2357
interesting_ids=interesting_ids,
2358
other_rev_id=parents[1],
2359
merge_type=merge_type,
2360
show_base=show_base,
2361
reprocess=reprocess)
2347
2364
if conflicts > 0:
2375
2392
aliases = ['merge-revert']
2377
2394
def run(self, revision=None, no_backup=False, file_list=None):
2378
from bzrlib.commands import parse_spec
2379
2395
if file_list is not None:
2380
2396
if len(file_list) == 0:
2381
raise BzrCommandError("No files specified")
2397
raise errors.BzrCommandError("No files specified")
2387
2403
# FIXME should be tree.last_revision
2388
2404
rev_id = tree.last_revision()
2389
2405
elif len(revision) != 1:
2390
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2406
raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
2392
2408
rev_id = revision[0].in_history(tree.branch).rev_id
2393
2409
pb = ui.ui_factory.nested_progress_bar()
2479
2495
if other_branch is None:
2480
2496
other_branch = parent
2481
2497
if other_branch is None:
2482
raise BzrCommandError("No peer location known or specified.")
2498
raise errors.BzrCommandError("No peer location known or specified.")
2483
2499
print "Using last location: " + local_branch.get_parent()
2484
2500
remote_branch = Branch.open(other_branch)
2485
2501
if remote_branch.base == local_branch.base:
2614
2630
if revision is None:
2615
2631
revision_id = branch.last_revision()
2616
2632
elif len(revision) != 1:
2617
raise BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2633
raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2619
2635
revision_id = revision[0].in_history(branch).rev_id
2620
2636
file_id = tree.inventory.path2id(relpath)
2636
2652
def run(self, revision_id_list=None, revision=None):
2637
2653
import bzrlib.gpg as gpg
2638
2654
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')
2655
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
2640
2656
if revision_id_list is None and revision is None:
2641
raise BzrCommandError('You must supply either --revision or a revision_id')
2657
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
2642
2658
b = WorkingTree.open_containing(u'.')[0].branch
2643
2659
gpg_strategy = gpg.GPGStrategy(b.get_config())
2644
2660
if revision_id_list is not None:
2657
2673
if to_revid is None:
2658
2674
to_revno = b.revno()
2659
2675
if from_revno is None or to_revno is None:
2660
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
2676
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2661
2677
for revno in range(from_revno, to_revno + 1):
2662
2678
b.repository.sign_revision(b.get_rev_id(revno),
2665
raise BzrCommandError('Please supply either one revision, or a range.')
2681
raise errors.BzrCommandError('Please supply either one revision, or a range.')
2668
2684
class cmd_bind(Command):
2680
2696
b_other = Branch.open(location)
2682
2698
b.bind(b_other)
2683
except DivergedBranches:
2684
raise BzrCommandError('These branches have diverged.'
2685
' Try merging, and then bind again.')
2699
except errors.DivergedBranches:
2700
raise errors.BzrCommandError('These branches have diverged.'
2701
' Try merging, and then bind again.')
2688
2704
class cmd_unbind(Command):
2699
2715
b, relpath = Branch.open_containing(u'.')
2700
2716
if not b.unbind():
2701
raise BzrCommandError('Local branch is not bound')
2717
raise errors.BzrCommandError('Local branch is not bound')
2704
2720
class cmd_uncommit(Command):
2853
2869
url = 'readonly+' + url
2854
2870
t = get_transport(url)
2856
server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
2872
server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
2857
2873
elif port is not None:
2858
2874
if ':' in port:
2859
2875
host, port = port.split(':')
2863
2879
print 'listening on port: ', server.port
2864
2880
sys.stdout.flush()
2866
raise BzrCommandError("bzr serve requires one of --inet or --port")
2882
raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
2870
2886
# 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()):
2887
def _merge_helper(other_revision, base_revision,
2888
check_clean=True, ignore_zero=False,
2889
this_dir=None, backup_files=False,
2891
file_list=None, show_base=False, reprocess=False,
2892
pb=DummyProgress()):
2876
2893
"""Merge changes into a tree.
2900
2917
clients might prefer to call merge.merge_inner(), which has less magic
2903
from bzrlib.merge import Merger
2920
# Loading it late, so that we don't always have to import bzrlib.merge
2921
if merge_type is None:
2922
merge_type = _mod_merge.Merge3Merger
2904
2923
if this_dir is None:
2905
2924
this_dir = u'.'
2906
2925
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)
2926
if show_base and not merge_type is _mod_merge.Merge3Merger:
2927
raise errors.BzrCommandError("Show-base is not supported for this merge"
2928
" type. %s" % merge_type)
2910
2929
if reprocess and not merge_type.supports_reprocess:
2911
raise BzrCommandError("Conflict reduction is not supported for merge"
2912
" type %s." % merge_type)
2930
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
2931
" type %s." % merge_type)
2913
2932
if reprocess and show_base:
2914
raise BzrCommandError("Cannot do conflict reduction and show base.")
2933
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
2916
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
2935
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
2917
2937
merger.pp = ProgressPhase("Merge phase", 5, pb)
2918
2938
merger.pp.next_phase()
2919
2939
merger.check_basis(check_clean)