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
54
from bzrlib.option import Option
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
57
from bzrlib.workingtree import WorkingTree
60
59
def tree_files(file_list, default_branch=u'.'):
62
61
return internal_tree_files(file_list, default_branch)
63
except FileInWrongBranch, e:
64
raise BzrCommandError("%s is not in the same branch as %s" %
65
(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]))
68
67
# XXX: Bad function name; should possibly also be a class method of
78
77
:param file_list: Filenames to convert.
80
: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
82
82
:return: workingtree, [relative_paths]
84
84
if file_list is None or len(file_list) == 0:
85
85
return WorkingTree.open_containing(default_branch)[0], file_list
86
tree = WorkingTree.open_containing(file_list[0])[0]
86
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
88
88
for filename in file_list:
90
new_list.append(tree.relpath(filename))
90
new_list.append(tree.relpath(osutils.dereference_path(filename)))
91
91
except errors.PathNotChild:
92
raise FileInWrongBranch(tree.branch, filename)
92
raise errors.FileInWrongBranch(tree.branch, filename)
93
93
return tree, new_list
205
207
elif revision is not None:
206
208
for rev in revision:
208
raise BzrCommandError('You cannot specify a NULL revision.')
210
raise errors.BzrCommandError('You cannot specify a NULL'
209
212
revno, rev_id = rev.in_history(b)
210
213
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
216
class cmd_remove_tree(Command):
217
"""Remove the working tree from a given branch/checkout.
219
Since a lightweight checkout is little more than a working tree
220
this will refuse to run against one.
225
takes_args = ['location?']
227
def run(self, location='.'):
228
d = bzrdir.BzrDir.open(location)
231
working = d.open_workingtree()
232
except errors.NoWorkingTree:
233
raise errors.BzrCommandError("No working tree to remove")
234
except errors.NotLocalUrl:
235
raise errors.BzrCommandError("You cannot remove the working tree of a "
238
working_path = working.bzrdir.root_transport.base
239
branch_path = working.branch.bzrdir.root_transport.base
240
if working_path != branch_path:
241
raise errors.BzrCommandError("You cannot remove the working tree from "
242
"a lightweight checkout")
244
d.destroy_workingtree()
213
247
class cmd_revno(Command):
214
248
"""Show current revision number.
361
395
"""Show inventory of the current working copy or a revision.
363
397
It is possible to limit the output to a particular entry
364
type using the --kind option. For example; --kind file.
398
type using the --kind option. For example: --kind file.
400
It is also possible to restrict the list of files to a specific
401
set. For example: bzr inventory --show-ids this/file
367
404
takes_options = ['revision', 'show-ids', 'kind']
405
takes_args = ['file*']
370
def run(self, revision=None, show_ids=False, kind=None):
408
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
371
409
if kind and kind not in ['file', 'directory', 'symlink']:
372
raise BzrCommandError('invalid kind specified')
373
tree = WorkingTree.open_containing(u'.')[0]
375
inv = tree.read_working_inventory()
410
raise errors.BzrCommandError('invalid kind specified')
412
work_tree, file_list = tree_files(file_list)
414
if revision is not None:
377
415
if len(revision) > 1:
378
raise BzrCommandError('bzr inventory --revision takes'
379
' exactly one revision identifier')
380
inv = tree.branch.repository.get_revision_inventory(
381
revision[0].in_history(tree.branch).rev_id)
383
for path, entry in inv.entries():
416
raise errors.BzrCommandError('bzr inventory --revision takes'
417
' exactly one revision identifier')
418
revision_id = revision[0].in_history(work_tree.branch).rev_id
419
tree = work_tree.branch.repository.revision_tree(revision_id)
421
# We include work_tree as well as 'tree' here
422
# So that doing '-r 10 path/foo' will lookup whatever file
423
# exists now at 'path/foo' even if it has been renamed, as
424
# well as whatever files existed in revision 10 at path/foo
425
trees = [tree, work_tree]
430
if file_list is not None:
431
file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
432
require_versioned=True)
433
# find_ids_across_trees may include some paths that don't
435
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
436
for file_id in file_ids if file_id in tree)
438
entries = tree.inventory.entries()
440
for path, entry in entries:
384
441
if kind and kind != entry.kind:
588
646
to_transport, relpath = needed[-1]
589
647
to_transport.mkdir(relpath)
649
except errors.NoSuchFile:
592
650
new_transport = to_transport.clone('..')
593
651
needed.append((new_transport,
594
652
new_transport.relpath(to_transport.base)))
595
653
if new_transport.base == to_transport.base:
596
raise BzrCommandError("Could not create "
654
raise errors.BzrCommandError("Could not create "
598
656
dir_to = br_from.bzrdir.clone(location_url,
599
657
revision_id=br_from.last_revision())
600
658
br_to = dir_to.open_branch()
615
673
warning('This transport does not update the working '
616
674
'tree of: %s' % (br_to.base,))
617
675
count = br_to.pull(br_from, overwrite)
618
except NoWorkingTree:
676
except errors.NoWorkingTree:
619
677
count = br_to.pull(br_from, overwrite)
621
679
count = tree_to.pull(br_from, overwrite)
622
except DivergedBranches:
623
raise BzrCommandError("These branches have diverged."
624
" Try a merge then push with overwrite.")
680
except errors.DivergedBranches:
681
raise errors.BzrCommandError('These branches have diverged.'
682
' Try using "merge" and then "push".')
625
683
note('%d revision(s) pushed.' % (count,))
700
758
except errors.NoSuchRevision:
701
759
to_transport.delete_tree('.')
702
760
msg = "The branch %s has no revision %s." % (from_location, revision[0])
703
raise BzrCommandError(msg)
761
raise errors.BzrCommandError(msg)
704
762
except errors.UnlistableBranch:
705
763
osutils.rmtree(to_location)
706
764
msg = "The branch %s cannot be used as a --basis" % (basis,)
707
raise BzrCommandError(msg)
765
raise errors.BzrCommandError(msg)
709
767
branch.control_files.put_utf8('branch-name', name)
710
768
note('Branched %d revision(s).' % branch.revno())
889
950
tree, file_list = tree_files(file_list)
891
952
if file_list is None:
892
raise BzrCommandError('Specify one or more files to remove, or'
953
raise errors.BzrCommandError('Specify one or more files to'
954
' remove, or use --new.')
895
956
added = tree.changes_from(tree.basis_tree(),
896
957
specific_files=file_list).added
897
958
file_list = sorted([f[0] for f in added], reverse=True)
898
959
if len(file_list) == 0:
899
raise BzrCommandError('No matching files.')
960
raise errors.BzrCommandError('No matching files.')
900
961
tree.remove(file_list, verbose=verbose, to_file=self.outf)
1178
except FileInWrongBranch:
1241
except errors.FileInWrongBranch:
1179
1242
if len(file_list) != 2:
1180
raise BzrCommandError("Files are in different branches")
1243
raise errors.BzrCommandError("Files are in different branches")
1182
1245
tree1, file1 = WorkingTree.open_containing(file_list[0])
1183
1246
tree2, file2 = WorkingTree.open_containing(file_list[1])
1184
1247
if file1 != "" or file2 != "":
1185
1248
# FIXME diff those two files. rbc 20051123
1186
raise BzrCommandError("Files are in different branches")
1249
raise errors.BzrCommandError("Files are in different branches")
1187
1250
file_list = None
1188
except NotBranchError:
1251
except errors.NotBranchError:
1189
1252
if (revision is not None and len(revision) == 2
1190
1253
and not revision[0].needs_branch()
1191
1254
and not revision[1].needs_branch()):
1504
1574
class cmd_ignore(Command):
1505
"""Ignore a command or pattern.
1575
"""Ignore specified files or patterns.
1507
1577
To remove patterns from the ignore list, edit the .bzrignore file.
1579
Trailing slashes on patterns are ignored.
1509
1580
If the pattern contains a slash, it is compared to the whole path
1510
1581
from the branch root. Otherwise, it is compared to only the last
1511
1582
component of the path. To match a file only in the root directory,
1585
Ignore patterns specifying absolute paths are not allowed.
1514
1587
Ignore patterns are case-insensitive on case-insensitive systems.
1516
1589
Note: wildcards must be quoted from the shell on Unix.
1519
1592
bzr ignore ./Makefile
1520
1593
bzr ignore '*.class'
1522
# TODO: Complain if the filename is absolute
1523
takes_args = ['name_pattern?']
1595
takes_args = ['name_pattern*']
1524
1596
takes_options = [
1525
1597
Option('old-default-rules',
1526
1598
help='Out the ignore rules bzr < 0.9 always used.')
1529
def run(self, name_pattern=None, old_default_rules=None):
1601
def run(self, name_pattern_list=None, old_default_rules=None):
1530
1602
from bzrlib.atomicfile import AtomicFile
1531
1603
if old_default_rules is not None:
1532
1604
# dump the rules and exit
1533
1605
for pattern in ignores.OLD_DEFAULTS:
1536
if name_pattern is None:
1537
raise BzrCommandError("ignore requires a NAME_PATTERN")
1608
if not name_pattern_list:
1609
raise errors.BzrCommandError("ignore requires at least one "
1610
"NAME_PATTERN or --old-default-rules")
1611
for name_pattern in name_pattern_list:
1612
if name_pattern[0] == '/':
1613
raise errors.BzrCommandError(
1614
"NAME_PATTERN should not be an absolute path")
1538
1615
tree, relpath = WorkingTree.open_containing(u'.')
1539
1616
ifn = tree.abspath('.bzrignore')
1540
1617
if os.path.exists(ifn):
1624
1704
tgz .tar.gz, .tgz
1627
takes_args = ['dest']
1707
takes_args = ['dest', 'branch?']
1628
1708
takes_options = ['revision', 'format', 'root']
1629
def run(self, dest, revision=None, format=None, root=None):
1709
def run(self, dest, branch=None, revision=None, format=None, root=None):
1630
1710
from bzrlib.export import export
1631
tree = WorkingTree.open_containing(u'.')[0]
1713
tree = WorkingTree.open_containing(u'.')[0]
1716
b = Branch.open(branch)
1633
1718
if revision is None:
1634
1719
# should be tree.last_revision FIXME
1635
1720
rev_id = b.last_revision()
1637
1722
if len(revision) != 1:
1638
raise BzrError('bzr export --revision takes exactly 1 argument')
1723
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1639
1724
rev_id = revision[0].in_history(b).rev_id
1640
1725
t = b.repository.revision_tree(rev_id)
1642
1727
export(t, dest, format, root)
1643
1728
except errors.NoSuchExportFormat, e:
1644
raise BzrCommandError('Unsupported export format: %s' % e.format)
1729
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1647
1732
class cmd_cat(Command):
1648
1733
"""Write a file's text from a previous revision."""
1650
takes_options = ['revision']
1735
takes_options = ['revision', 'name-from-revision']
1651
1736
takes_args = ['filename']
1653
1738
@display_command
1654
def run(self, filename, revision=None):
1739
def run(self, filename, revision=None, name_from_revision=False):
1655
1740
if revision is not None and len(revision) != 1:
1656
raise BzrCommandError("bzr cat --revision takes exactly one number")
1741
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1659
1746
tree, relpath = WorkingTree.open_containing(filename)
1660
1747
b = tree.branch
1661
except NotBranchError:
1748
except errors.NotBranchError:
1664
1751
if tree is None:
1669
1756
revision_id = b.last_revision()
1671
1758
revision_id = revision[0].in_history(b).rev_id
1672
b.print_file(relpath, revision_id)
1760
cur_file_id = tree.path2id(relpath)
1761
rev_tree = b.repository.revision_tree(revision_id)
1762
old_file_id = rev_tree.path2id(relpath)
1764
if name_from_revision:
1765
if old_file_id is None:
1766
raise errors.BzrCommandError("%r is not present in revision %s"
1767
% (filename, revision_id))
1769
rev_tree.print_file(old_file_id)
1770
elif cur_file_id is not None:
1771
rev_tree.print_file(cur_file_id)
1772
elif old_file_id is not None:
1773
rev_tree.print_file(old_file_id)
1775
raise errors.BzrCommandError("%r is not present in revision %s" %
1776
(filename, revision_id))
1675
1779
class cmd_local_time_offset(Command):
1729
1833
StrictCommitFailed)
1730
1834
from bzrlib.msgeditor import edit_commit_message, \
1731
1835
make_commit_message_template
1732
from tempfile import TemporaryFile
1734
1837
# TODO: Need a blackbox test for invoking the external editor; may be
1735
1838
# slightly problematic to run this cross-platform.
1737
1840
# TODO: do more checks that the commit will succeed before
1738
1841
# spending the user's valuable time typing a commit message.
1740
# TODO: if the commit *does* happen to fail, then save the commit
1741
# message to a temporary file where it can be recovered
1742
1842
tree, selected_list = tree_files(selected_list)
1743
1843
if selected_list == ['']:
1744
1844
# workaround - commit of root of tree should be exactly the same
1752
1852
template = make_commit_message_template(tree, selected_list)
1753
1853
message = edit_commit_message(template)
1754
1854
if message is None:
1755
raise BzrCommandError("please specify a commit message"
1756
" with either --message or --file")
1855
raise errors.BzrCommandError("please specify a commit message"
1856
" with either --message or --file")
1757
1857
elif message and file:
1758
raise BzrCommandError("please specify either --message or --file")
1858
raise errors.BzrCommandError("please specify either --message or --file")
1761
1861
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1763
1863
if message == "":
1764
raise BzrCommandError("empty commit message specified")
1864
raise errors.BzrCommandError("empty commit message specified")
1767
1867
reporter = ReportCommitToLog()
1769
1869
reporter = NullCommitReporter()
1871
msgfilename = self._save_commit_message(message, tree.basedir)
1772
1873
tree.commit(message, specific_files=selected_list,
1773
1874
allow_pointless=unchanged, strict=strict, local=local,
1774
1875
reporter=reporter)
1876
if msgfilename is not None:
1878
os.unlink(msgfilename)
1880
warning("failed to unlink %s: %s; ignored", msgfilename, e)
1775
1881
except PointlessCommit:
1776
1882
# FIXME: This should really happen before the file is read in;
1777
1883
# perhaps prepare the commit; get the message; then actually commit
1778
raise BzrCommandError("no changes to commit."
1884
if msgfilename is not None:
1885
raise errors.BzrCommandError("no changes to commit."
1886
" use --unchanged to commit anyhow\n"
1887
"Commit message saved. To reuse the message,"
1888
" do\nbzr commit --file " + msgfilename)
1890
raise errors.BzrCommandError("no changes to commit."
1779
1891
" use --unchanged to commit anyhow")
1780
1892
except ConflictsInTree:
1781
raise BzrCommandError("Conflicts detected in working tree. "
1782
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1893
if msgfilename is not None:
1894
raise errors.BzrCommandError('Conflicts detected in working '
1895
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1897
'Commit message saved. To reuse the message,'
1898
' do\nbzr commit --file ' + msgfilename)
1900
raise errors.BzrCommandError('Conflicts detected in working '
1901
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1783
1903
except StrictCommitFailed:
1784
raise BzrCommandError("Commit refused because there are unknown "
1785
"files in the working tree.")
1904
if msgfilename is not None:
1905
raise errors.BzrCommandError("Commit refused because there are"
1906
" unknown files in the working tree.\n"
1907
"Commit message saved. To reuse the message,"
1908
" do\nbzr commit --file " + msgfilename)
1910
raise errors.BzrCommandError("Commit refused because there are"
1911
" unknown files in the working tree.")
1786
1912
except errors.BoundBranchOutOfDate, e:
1787
raise BzrCommandError(str(e) + "\n"
1913
if msgfilename is not None:
1914
raise errors.BzrCommandError(str(e) + "\n"
1915
'To commit to master branch, run update and then commit.\n'
1916
'You can also pass --local to commit to continue working '
1918
'Commit message saved. To reuse the message,'
1919
' do\nbzr commit --file ' + msgfilename)
1921
raise errors.BzrCommandError(str(e) + "\n"
1788
1922
'To commit to master branch, run update and then commit.\n'
1789
1923
'You can also pass --local to commit to continue working '
1790
1924
'disconnected.')
1926
def _save_commit_message(self, message, basedir):
1927
# save the commit message and only unlink it if the commit was
1931
tmp_fileno, msgfilename = tempfile.mkstemp(prefix='bzr-commit-',
1935
# No access to working dir, try $TMP
1936
tmp_fileno, msgfilename = tempfile.mkstemp(prefix='bzr-commit-')
1938
# We can't create a temp file, try to work without it
1941
os.write(tmp_fileno, message.encode(bzrlib.user_encoding, 'replace'))
1943
os.close(tmp_fileno)
1792
1947
class cmd_check(Command):
1793
1948
"""Validate consistency of branch history.
1985
2121
if cache_dir is not None:
1986
2122
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
1987
# we don't want progress meters from the tests to go to the
1988
# real output; and we don't want log messages cluttering up
1990
save_ui = ui.ui_factory
1991
2123
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1992
2124
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1994
info('running tests...')
2126
if testspecs_list is not None:
2127
pattern = '|'.join(testspecs_list)
2131
test_suite_factory = benchmarks.test_suite
2134
# TODO: should possibly lock the history file...
2135
benchfile = open(".perf_history", "at")
2137
test_suite_factory = None
1996
ui.ui_factory = ui.SilentUIFactory()
1997
if testspecs_list is not None:
1998
pattern = '|'.join(testspecs_list)
2002
test_suite_factory = benchmarks.test_suite
2005
benchfile = open(".perf_history", "at")
2007
test_suite_factory = None
2012
result = selftest(verbose=verbose,
2014
stop_on_failure=one,
2015
keep_output=keep_output,
2016
transport=transport,
2017
test_suite_factory=test_suite_factory,
2018
lsprof_timed=lsprof_timed,
2019
bench_history=benchfile)
2021
if benchfile is not None:
2024
info('tests passed')
2026
info('tests failed')
2027
return int(not result)
2142
result = selftest(verbose=verbose,
2144
stop_on_failure=one,
2145
keep_output=keep_output,
2146
transport=transport,
2147
test_suite_factory=test_suite_factory,
2148
lsprof_timed=lsprof_timed,
2149
bench_history=benchfile)
2029
ui.ui_factory = save_ui
2151
if benchfile is not None:
2154
info('tests passed')
2156
info('tests failed')
2157
return int(not result)
2032
2160
class cmd_version(Command):
2125
2253
' from a working copy, instead of branch changes')]
2127
2255
def help(self):
2128
from merge import merge_type_help
2129
2256
from inspect import getdoc
2130
return getdoc(self) + '\n' + merge_type_help()
2257
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2132
2259
def run(self, branch=None, revision=None, force=False, merge_type=None,
2133
2260
show_base=False, reprocess=False, remember=False,
2134
2261
uncommitted=False):
2135
2262
if merge_type is None:
2136
merge_type = Merge3Merger
2263
merge_type = _mod_merge.Merge3Merger
2138
2265
tree = WorkingTree.open_containing(u'.')[0]
2140
2267
if branch is not None:
2142
2269
reader = bundle.read_bundle_from_url(branch)
2270
except errors.NotABundle:
2144
2271
pass # Continue on considering this url a Branch
2146
2273
conflicts = merge_bundle(reader, tree, not force, merge_type,
2263
2391
def help(self):
2264
from merge import merge_type_help
2265
2392
from inspect import getdoc
2266
return getdoc(self) + '\n' + merge_type_help()
2393
return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2268
2395
def run(self, file_list=None, merge_type=None, show_base=False,
2269
2396
reprocess=False):
2270
from bzrlib.merge import merge_inner, transform_tree
2271
2397
if merge_type is None:
2272
merge_type = Merge3Merger
2398
merge_type = _mod_merge.Merge3Merger
2273
2399
tree, file_list = tree_files(file_list)
2274
2400
tree.lock_write()
2276
2402
parents = tree.get_parent_ids()
2277
2403
if len(parents) != 2:
2278
raise BzrCommandError("Sorry, remerge only works after normal"
2279
" merges. Not cherrypicking or"
2404
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2405
" merges. Not cherrypicking or"
2281
2407
repository = tree.branch.repository
2282
2408
base_revision = common_ancestor(parents[0],
2283
2409
parents[1], repository)
2299
2425
for name, ie in tree.inventory.iter_entries(file_id):
2300
2426
interesting_ids.add(ie.file_id)
2301
2427
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2302
transform_tree(tree, tree.basis_tree(), interesting_ids)
2429
# Remerge only supports resolving contents conflicts
2430
allowed_conflicts = ('text conflict', 'contents conflict')
2431
restore_files = [c.path for c in conflicts
2432
if c.typestring in allowed_conflicts]
2433
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2303
2434
tree.set_conflicts(ConflictList(new_conflicts))
2304
if file_list is None:
2305
restore_files = list(tree.iter_conflicts())
2435
if file_list is not None:
2307
2436
restore_files = file_list
2308
2437
for filename in restore_files:
2310
2439
restore(tree.abspath(filename))
2311
except NotConflicted:
2440
except errors.NotConflicted:
2313
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2315
interesting_ids=interesting_ids,
2316
other_rev_id=parents[1],
2317
merge_type=merge_type,
2318
show_base=show_base,
2319
reprocess=reprocess)
2442
conflicts = _mod_merge.merge_inner(
2443
tree.branch, other_tree, base_tree,
2445
interesting_ids=interesting_ids,
2446
other_rev_id=parents[1],
2447
merge_type=merge_type,
2448
show_base=show_base,
2449
reprocess=reprocess)
2322
2452
if conflicts > 0:
2327
2458
class cmd_revert(Command):
2328
"""Reverse all changes since the last commit.
2330
Only versioned files are affected. Specify filenames to revert only
2331
those files. By default, any files that are changed will be backed up
2332
first. Backup files have a '~' appended to their name.
2459
"""Revert files to a previous revision.
2461
Giving a list of files will revert only those files. Otherwise, all files
2462
will be reverted. If the revision is not specified with '--revision', the
2463
last committed revision is used.
2465
To remove only some changes, without reverting to a prior version, use
2466
merge instead. For example, "merge . --r-2..-3" will remove the changes
2467
introduced by -2, without affecting the changes introduced by -1. Or
2468
to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
2470
By default, any files that have been manually changed will be backed up
2471
first. (Files changed only by merge are not backed up.) Backup files have
2472
'.~#~' appended to their name, where # is a number.
2474
When you provide files, you can use their current pathname or the pathname
2475
from the target revision. So you can use revert to "undelete" a file by
2476
name. If you name a directory, all the contents of that directory will be
2334
2479
takes_options = ['revision', 'no-backup']
2335
2480
takes_args = ['file*']
2336
2481
aliases = ['merge-revert']
2338
2483
def run(self, revision=None, no_backup=False, file_list=None):
2339
from bzrlib.commands import parse_spec
2340
2484
if file_list is not None:
2341
2485
if len(file_list) == 0:
2342
raise BzrCommandError("No files specified")
2486
raise errors.BzrCommandError("No files specified")
2363
2507
class cmd_assert_fail(Command):
2364
2508
"""Test reporting of assertion failures"""
2509
# intended just for use in testing
2367
assert False, "always fails"
2514
raise AssertionError("always fails")
2370
2517
class cmd_help(Command):
2371
2518
"""Show help on a command or other topic.
2373
For a list of all available commands, say 'bzr help commands'."""
2520
For a list of all available commands, say 'bzr help commands'.
2374
2522
takes_options = [Option('long', 'show help on all commands')]
2375
2523
takes_args = ['topic?']
2376
2524
aliases = ['?', '--help', '-?', '-h']
2378
2526
@display_command
2379
2527
def run(self, topic=None, long=False):
2381
2529
if topic is None and long:
2382
2530
topic = "commands"
2531
bzrlib.help.help(topic)
2386
2534
class cmd_shell_complete(Command):
2387
2535
"""Show appropriate completions for context.
2389
For a list of all available commands, say 'bzr shell-complete'."""
2537
For a list of all available commands, say 'bzr shell-complete'.
2390
2539
takes_args = ['context?']
2391
2540
aliases = ['s-c']
2824
2975
print 'listening on port: ', server.port
2825
2976
sys.stdout.flush()
2827
raise BzrCommandError("bzr serve requires one of --inet or --port")
2978
raise errors.BzrCommandError("bzr serve requires one of --inet or --port")
2831
2982
# command-line interpretation helper for merge-related commands
2832
def merge(other_revision, base_revision,
2833
check_clean=True, ignore_zero=False,
2834
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2835
file_list=None, show_base=False, reprocess=False,
2836
pb=DummyProgress()):
2983
def _merge_helper(other_revision, base_revision,
2984
check_clean=True, ignore_zero=False,
2985
this_dir=None, backup_files=False,
2987
file_list=None, show_base=False, reprocess=False,
2988
pb=DummyProgress()):
2837
2989
"""Merge changes into a tree.
2861
3013
clients might prefer to call merge.merge_inner(), which has less magic
2864
from bzrlib.merge import Merger
3016
# Loading it late, so that we don't always have to import bzrlib.merge
3017
if merge_type is None:
3018
merge_type = _mod_merge.Merge3Merger
2865
3019
if this_dir is None:
2866
3020
this_dir = u'.'
2867
3021
this_tree = WorkingTree.open_containing(this_dir)[0]
2868
if show_base and not merge_type is Merge3Merger:
2869
raise BzrCommandError("Show-base is not supported for this merge"
2870
" type. %s" % merge_type)
3022
if show_base and not merge_type is _mod_merge.Merge3Merger:
3023
raise errors.BzrCommandError("Show-base is not supported for this merge"
3024
" type. %s" % merge_type)
2871
3025
if reprocess and not merge_type.supports_reprocess:
2872
raise BzrCommandError("Conflict reduction is not supported for merge"
2873
" type %s." % merge_type)
3026
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3027
" type %s." % merge_type)
2874
3028
if reprocess and show_base:
2875
raise BzrCommandError("Cannot do conflict reduction and show base.")
3029
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
2877
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
3031
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
2878
3033
merger.pp = ProgressPhase("Merge phase", 5, pb)
2879
3034
merger.pp.next_phase()
2880
3035
merger.check_basis(check_clean)