23
from shutil import rmtree
28
from bzrlib.branch import Branch
29
import bzrlib.bzrdir as bzrdir
26
from bzrlib.branch import Branch, BranchReferenceFormat
27
from bzrlib import (bundle, branch, bzrdir, errors, osutils, ui, config,
30
29
from bzrlib.bundle import read_bundle_from_url
31
from bzrlib.bundle.read_bundle import BundleReader
32
30
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
33
31
from bzrlib.commands import Command, display_command
34
import bzrlib.errors as errors
35
32
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
36
33
NotBranchError, DivergedBranches, NotConflicted,
37
34
NoSuchFile, NoWorkingTree, FileInWrongBranch,
38
35
NotVersionedError, NotABundle)
39
from bzrlib.log import show_one_log
40
36
from bzrlib.merge import Merge3Merger
41
37
from bzrlib.option import Option
43
38
from bzrlib.progress import DummyProgress, ProgressPhase
44
39
from bzrlib.revision import common_ancestor
45
40
from bzrlib.revisionspec import RevisionSpec
47
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
41
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
48
42
from bzrlib.transport.local import LocalTransport
50
43
import bzrlib.urlutils as urlutils
51
44
from bzrlib.workingtree import WorkingTree
95
88
return bzrdir.BzrDirMetaFormat1()
96
89
if typestring == "metaweave":
97
90
format = bzrdir.BzrDirMetaFormat1()
98
format.repository_format = bzrlib.repository.RepositoryFormat7()
91
format.repository_format = repository.RepositoryFormat7()
100
93
if typestring == "knit":
101
94
format = bzrdir.BzrDirMetaFormat1()
102
format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
95
format.repository_format = repository.RepositoryFormatKnit1()
104
97
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
105
98
"metaweave and weave" % typestring
407
400
from one into the other. Once one branch has merged, the other should
408
401
be able to pull it again.
410
If branches have diverged, you can use 'bzr merge' to pull the text changes
411
from one into the other. Once one branch has merged, the other should
412
be able to pull it again.
414
403
If you want to forget your local changes and just update your branch to
415
404
match the remote one, use pull --overwrite.
417
406
If there is no default location set, the first pull will set it. After
418
407
that, you can omit the location to use the default. To change the
419
default, use --remember.
408
default, use --remember. The value will only be saved if the remote
409
location can be accessed.
422
412
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
507
497
If there is no default push location set, the first push will set it.
508
498
After that, you can omit the location to use the default. To change the
509
default, use --remember.
499
default, use --remember. The value will only be saved if the remote
500
location can be accessed.
512
503
takes_options = ['remember', 'overwrite', 'verbose',
531
522
display_url = urlutils.unescape_for_display(stored_loc,
532
523
self.outf.encoding)
533
self.outf.write("Using saved location: %s" % display_url)
524
self.outf.write("Using saved location: %s\n" % display_url)
534
525
location = stored_loc
536
527
transport = get_transport(location)
537
528
location_url = transport.base
538
if br_from.get_push_location() is None or remember:
539
br_from.set_push_location(location_url)
543
dir_to = bzrlib.bzrdir.BzrDir.open(location_url)
532
dir_to = bzrdir.BzrDir.open(location_url)
544
533
br_to = dir_to.open_branch()
545
534
except NotBranchError:
546
535
# create a branch.
572
561
revision_id=br_from.last_revision())
573
562
br_to = dir_to.open_branch()
574
563
count = len(br_to.revision_history())
564
# We successfully created the target, remember it
565
if br_from.get_push_location() is None or remember:
566
br_from.set_push_location(br_to.base)
568
# We were able to connect to the remote location, so remember it
569
# we don't need to successfully push because of possible divergence.
570
if br_from.get_push_location() is None or remember:
571
br_from.set_push_location(br_to.base)
576
572
old_rh = br_to.revision_history()
619
615
def run(self, from_location, to_location=None, revision=None, basis=None):
620
616
from bzrlib.transport import get_transport
621
from bzrlib.osutils import rmtree
622
617
if revision is None:
623
618
revision = [None]
624
619
elif len(revision) > 1:
654
649
to_transport = get_transport(to_location)
656
651
to_transport.mkdir('.')
657
except bzrlib.errors.FileExists:
652
except errors.FileExists:
658
653
raise BzrCommandError('Target directory "%s" already'
659
654
' exists.' % to_location)
660
except bzrlib.errors.NoSuchFile:
655
except errors.NoSuchFile:
661
656
raise BzrCommandError('Parent of "%s" does not exist.' %
665
660
dir = br_from.bzrdir.sprout(to_transport.base,
666
661
revision_id, basis_dir)
667
662
branch = dir.open_branch()
668
except bzrlib.errors.NoSuchRevision:
663
except errors.NoSuchRevision:
669
664
to_transport.delete_tree('.')
670
665
msg = "The branch %s has no revision %s." % (from_location, revision[0])
671
666
raise BzrCommandError(msg)
672
except bzrlib.errors.UnlistableBranch:
667
except errors.UnlistableBranch:
668
osutils.rmtree(to_location)
674
669
msg = "The branch %s cannot be used as a --basis" % (basis,)
675
670
raise BzrCommandError(msg)
710
705
"such access, and also support local commits."
714
710
def run(self, branch_location=None, to_location=None, revision=None, basis=None,
715
711
lightweight=False):
719
715
raise BzrCommandError(
720
716
'bzr checkout --revision takes exactly 1 revision value')
721
717
if branch_location is None:
722
branch_location = bzrlib.osutils.getcwd()
718
branch_location = osutils.getcwd()
723
719
to_location = branch_location
724
720
source = Branch.open(branch_location)
725
721
if len(revision) == 1 and revision[0] is not None:
731
727
# if the source and to_location are the same,
732
728
# and there is no working tree,
733
729
# then reconstitute a branch
734
if (bzrlib.osutils.abspath(to_location) ==
735
bzrlib.osutils.abspath(branch_location)):
730
if (osutils.abspath(to_location) ==
731
osutils.abspath(branch_location)):
737
733
source.bzrdir.open_workingtree()
738
734
except errors.NoWorkingTree:
752
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
753
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
748
old_format = bzrdir.BzrDirFormat.get_default_format()
749
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
756
752
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
757
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
753
branch.BranchReferenceFormat().initialize(checkout, source)
759
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
755
checkout_branch = bzrdir.BzrDir.create_branch_convenience(
760
756
to_location, force_new_tree=False)
761
757
checkout = checkout_branch.bzrdir
762
758
checkout_branch.bind(source)
765
761
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
766
762
checkout.create_workingtree(revision_id)
768
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
764
bzrdir.BzrDirFormat.set_default_format(old_format)
771
767
class cmd_renames(Command):
780
776
def run(self, dir=u'.'):
777
from bzrlib.tree import find_renames
781
778
tree = WorkingTree.open_containing(dir)[0]
782
779
old_inv = tree.basis_tree().inventory
783
780
new_inv = tree.read_working_inventory()
785
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
781
renames = list(find_renames(old_inv, new_inv))
787
783
for old_name, new_name in renames:
788
784
self.outf.write("%s => %s\n" % (old_name, new_name))
937
933
def run(self, branch="."):
938
934
from bzrlib.reconcile import reconcile
939
dir = bzrlib.bzrdir.BzrDir.open(branch)
935
dir = bzrdir.BzrDir.open(branch)
943
939
class cmd_revision_history(Command):
944
"""Display list of revision ids on this branch."""
940
"""Display the list of revision ids on a branch."""
941
takes_args = ['location?']
949
branch = WorkingTree.open_containing(u'.')[0].branch
950
for patchid in branch.revision_history():
951
self.outf.write(patchid)
946
def run(self, location="."):
947
branch = Branch.open_containing(location)[0]
948
for revid in branch.revision_history():
949
self.outf.write(revid)
952
950
self.outf.write('\n')
955
953
class cmd_ancestry(Command):
956
954
"""List all revisions merged into this branch."""
955
takes_args = ['location?']
961
tree = WorkingTree.open_containing(u'.')[0]
963
# FIXME. should be tree.last_revision
964
revision_ids = b.repository.get_ancestry(b.last_revision())
960
def run(self, location="."):
962
wt = WorkingTree.open_containing(location)[0]
963
except errors.NoWorkingTree:
964
b = Branch.open(location)
965
last_revision = b.last_revision()
968
last_revision = wt.last_revision()
970
revision_ids = b.repository.get_ancestry(last_revision)
965
971
assert revision_ids[0] == None
966
972
revision_ids.pop(0)
967
973
for revision_id in revision_ids:
1204
1209
if file_id in basis_inv:
1206
1211
path = inv.id2path(file_id)
1207
if not os.access(bzrlib.osutils.abspath(path), os.F_OK):
1212
if not os.access(osutils.abspath(path), os.F_OK):
1209
1214
self.outf.write(path + '\n')
1319
1324
(rev2, rev1) = (rev1, rev2)
1321
1326
if (log_format == None):
1322
default = bzrlib.config.BranchConfig(b).log_format()
1323
log_format = get_log_format(long=long, short=short, line=line, default=default)
1327
default = b.get_config().log_format()
1328
log_format = get_log_format(long=long, short=short, line=line,
1324
1330
lf = log_formatter(log_format,
1325
1331
show_ids=show_ids,
1326
1332
to_file=self.outf,
1362
1368
b = tree.branch
1363
1369
inv = tree.read_working_inventory()
1364
1370
file_id = inv.path2id(relpath)
1365
for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
1371
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
1366
1372
self.outf.write("%6d %s\n" % (revno, what))
1424
1430
"""List unknown files."""
1425
1431
@display_command
1427
from bzrlib.osutils import quotefn
1428
1433
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1429
self.outf.write(quotefn(f) + '\n')
1434
self.outf.write(osutils.quotefn(f) + '\n')
1432
1437
class cmd_ignore(Command):
1680
1685
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1682
1687
if message == "":
1683
raise BzrCommandError("empty commit message specified")
1688
raise BzrCommandError("empty commit message specified")
1686
1691
reporter = ReportCommitToLog()
1694
1699
except PointlessCommit:
1695
1700
# FIXME: This should really happen before the file is read in;
1696
1701
# perhaps prepare the commit; get the message; then actually commit
1697
raise BzrCommandError("no changes to commit",
1698
["use --unchanged to commit anyhow"])
1702
raise BzrCommandError("no changes to commit."
1703
" use --unchanged to commit anyhow")
1699
1704
except ConflictsInTree:
1700
1705
raise BzrCommandError("Conflicts detected in working tree. "
1701
1706
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
1778
1783
@display_command
1779
1784
def run(self, email=False):
1781
b = WorkingTree.open_containing(u'.')[0].branch
1782
config = bzrlib.config.BranchConfig(b)
1786
c = WorkingTree.open_containing(u'.')[0].branch.get_config()
1783
1787
except NotBranchError:
1784
config = bzrlib.config.GlobalConfig()
1788
c = config.GlobalConfig()
1787
print config.user_email()
1790
print c.user_email()
1789
print config.username()
1792
1795
class cmd_nick(Command):
1872
1875
# we don't want progress meters from the tests to go to the
1873
1876
# real output; and we don't want log messages cluttering up
1874
1877
# the real logs.
1875
save_ui = bzrlib.ui.ui_factory
1876
print '%10s: %s' % ('bzr', bzrlib.osutils.realpath(sys.argv[0]))
1878
save_ui = ui.ui_factory
1879
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1877
1880
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1879
bzrlib.trace.info('running tests...')
1882
info('running tests...')
1881
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1884
ui.ui_factory = ui.SilentUIFactory()
1882
1885
if testspecs_list is not None:
1883
1886
pattern = '|'.join(testspecs_list)
1899
1902
test_suite_factory=test_suite_factory,
1900
1903
lsprof_timed=lsprof_timed)
1902
bzrlib.trace.info('tests passed')
1905
info('tests passed')
1904
bzrlib.trace.info('tests failed')
1907
info('tests failed')
1905
1908
return int(not result)
1907
bzrlib.ui.ui_factory = save_ui
1910
ui.ui_factory = save_ui
1910
1913
def _get_bzr_branch():
1911
1914
"""If bzr is run from a branch, return Branch or None"""
1912
import bzrlib.errors
1913
from bzrlib.branch import Branch
1914
from bzrlib.osutils import abspath
1915
1915
from os.path import dirname
1918
branch = Branch.open(dirname(abspath(dirname(__file__))))
1918
branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1920
except bzrlib.errors.BzrError:
1920
except errors.BzrError:
1924
1924
def show_version():
1925
1926
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1926
1927
# is bzrlib itself in a branch?
1927
1928
branch = _get_bzr_branch()
1993
1994
base_rev_id = common_ancestor(last1, last2, source)
1995
1996
print 'merge base is revision %s' % base_rev_id
1999
if base_revno is None:
2000
raise bzrlib.errors.UnrelatedBranches()
2002
print ' r%-6d in %s' % (base_revno, branch)
2004
other_revno = branch2.revision_id_to_revno(base_revid)
2006
print ' r%-6d in %s' % (other_revno, other)
2010
1999
class cmd_merge(Command):
2011
2000
"""Perform a three-way merge.
2013
The branch is the branch you will merge from. By default, it will
2014
merge the latest revision. If you specify a revision, that
2015
revision will be merged. If you specify two revisions, the first
2016
will be used as a BASE, and the second one as OTHER. Revision
2017
numbers are always relative to the specified branch.
2002
The branch is the branch you will merge from. By default, it will merge
2003
the latest revision. If you specify a revision, that revision will be
2004
merged. If you specify two revisions, the first will be used as a BASE,
2005
and the second one as OTHER. Revision numbers are always relative to the
2019
2008
By default, bzr will try to merge in all new work from the other
2020
2009
branch, automatically determining an appropriate base. If this
2030
2019
If there is no default branch set, the first merge will set it. After
2031
2020
that, you can omit the branch to use the default. To change the
2032
default, use --remember.
2021
default, use --remember. The value will only be saved if the remote
2022
location can be accessed.
2106
2096
interesting_files = [path]
2108
2098
interesting_files = None
2109
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2099
pb = ui.ui_factory.nested_progress_bar()
2112
2102
conflict_count = merge(other, base, check_clean=(not force),
2188
2178
pending_merges = tree.pending_merges()
2189
2179
if len(pending_merges) != 1:
2190
2180
raise BzrCommandError("Sorry, remerge only works after normal"
2191
+ " merges. Not cherrypicking or"
2181
" merges. Not cherrypicking or"
2193
2183
repository = tree.branch.repository
2194
2184
base_revision = common_ancestor(tree.branch.last_revision(),
2195
2185
pending_merges[0], repository)
2259
2249
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2261
2251
rev_id = revision[0].in_history(tree.branch).rev_id
2262
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2252
pb = ui.ui_factory.nested_progress_bar()
2264
2254
tree.revert(file_list,
2265
2255
tree.branch.repository.revision_tree(rev_id),
2313
2303
takes_args = ['from_branch', 'to_branch']
2314
2304
def run(self, from_branch, to_branch):
2315
2305
from bzrlib.fetch import Fetcher
2316
from bzrlib.branch import Branch
2317
2306
from_b = Branch.open(from_branch)
2318
2307
to_b = Branch.open(to_branch)
2319
2308
Fetcher(to_b, from_b)
2328
encoding_type = 'replace'
2340
2331
def run(self, other_branch=None, reverse=False, mine_only=False,
2341
2332
theirs_only=False, log_format=None, long=False, short=False, line=False,
2342
2333
show_ids=False, verbose=False):
2343
2334
from bzrlib.missing import find_unmerged, iter_log_data
2344
2335
from bzrlib.log import log_formatter
2345
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
2336
local_branch = Branch.open_containing(u".")[0]
2346
2337
parent = local_branch.get_parent()
2347
2338
if other_branch is None:
2348
2339
other_branch = parent
2349
2340
if other_branch is None:
2350
2341
raise BzrCommandError("No missing location known or specified.")
2351
2342
print "Using last location: " + local_branch.get_parent()
2352
remote_branch = bzrlib.branch.Branch.open(other_branch)
2343
remote_branch = Branch.open(other_branch)
2353
2344
if remote_branch.base == local_branch.base:
2354
2345
remote_branch = local_branch
2355
2346
local_branch.lock_read()
2359
2350
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2360
2351
if (log_format == None):
2361
default = bzrlib.config.BranchConfig(local_branch).log_format()
2362
log_format = get_log_format(long=long, short=short, line=line, default=default)
2363
lf = log_formatter(log_format, sys.stdout,
2352
default = local_branch.get_config().log_format()
2353
log_format = get_log_format(long=long, short=short,
2354
line=line, default=default)
2355
lf = log_formatter(log_format,
2364
2357
show_ids=show_ids,
2365
2358
show_timezone='original')
2366
2359
if reverse is False:
2424
2417
class cmd_testament(Command):
2425
2418
"""Show testament (signing-form) of a revision."""
2426
takes_options = ['revision', 'long']
2419
takes_options = ['revision', 'long',
2420
Option('strict', help='Produce a strict-format'
2427
2422
takes_args = ['branch?']
2428
2423
@display_command
2429
def run(self, branch=u'.', revision=None, long=False):
2430
from bzrlib.testament import Testament
2424
def run(self, branch=u'.', revision=None, long=False, strict=False):
2425
from bzrlib.testament import Testament, StrictTestament
2427
testament_class = StrictTestament
2429
testament_class = Testament
2431
2430
b = WorkingTree.open_containing(branch)[0].branch
2435
2434
rev_id = b.last_revision()
2437
2436
rev_id = revision[0].in_history(b).rev_id
2438
t = Testament.from_revision(b.repository, rev_id)
2437
t = testament_class.from_revision(b.repository, rev_id)
2440
2439
sys.stdout.writelines(t.as_text_lines())
2456
2455
# TODO: annotate directories; showing when each file was last changed
2457
2456
# TODO: if the working copy is modified, show annotations on that
2458
2457
# with new uncommitted lines marked
2459
aliases = ['blame', 'praise']
2458
aliases = ['ann', 'blame', 'praise']
2460
2459
takes_args = ['filename']
2461
2460
takes_options = [Option('all', help='show annotations on all lines'),
2462
2461
Option('long', help='show date in annotations'),
2493
2492
takes_options = ['revision']
2495
2494
def run(self, revision_id_list=None, revision=None):
2496
import bzrlib.config as config
2497
2495
import bzrlib.gpg as gpg
2498
2496
if revision_id_list is not None and revision is not None:
2499
2497
raise BzrCommandError('You can only supply one of revision_id or --revision')
2500
2498
if revision_id_list is None and revision is None:
2501
2499
raise BzrCommandError('You must supply either --revision or a revision_id')
2502
2500
b = WorkingTree.open_containing(u'.')[0].branch
2503
gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
2501
gpg_strategy = gpg.GPGStrategy(b.get_config())
2504
2502
if revision_id_list is not None:
2505
2503
for revision_id in revision_id_list:
2506
2504
b.repository.sign_revision(revision_id, gpg_strategy)
2561
2559
raise BzrCommandError('Local branch is not bound')
2564
class cmd_uncommit(bzrlib.commands.Command):
2562
class cmd_uncommit(Command):
2565
2563
"""Remove the last committed revision.
2567
2565
--verbose will print out what is being removed.
2585
2583
def run(self, location=None,
2586
2584
dry_run=False, verbose=False,
2587
2585
revision=None, force=False):
2588
from bzrlib.branch import Branch
2589
2586
from bzrlib.log import log_formatter
2591
2588
from bzrlib.uncommit import uncommit