~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Robey Pointer
  • Date: 2006-07-01 19:03:33 UTC
  • mfrom: (1829 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1830.
  • Revision ID: robey@lag.net-20060701190333-f58465aec4bd3412
merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import codecs
21
21
import errno
22
22
import os
23
 
from shutil import rmtree
24
23
import sys
25
24
 
26
25
import bzrlib
27
 
import bzrlib.branch
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,
 
28
    repository, log)
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
42
 
import bzrlib.osutils
43
38
from bzrlib.progress import DummyProgress, ProgressPhase
44
39
from bzrlib.revision import common_ancestor
45
40
from bzrlib.revisionspec import RevisionSpec
46
 
import bzrlib.trace
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
49
 
import bzrlib.ui
50
43
import bzrlib.urlutils as urlutils
51
44
from bzrlib.workingtree import WorkingTree
52
45
 
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()
99
92
        return format
100
93
    if typestring == "knit":
101
94
        format = bzrdir.BzrDirMetaFormat1()
102
 
        format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
 
95
        format.repository_format = repository.RepositoryFormatKnit1()
103
96
        return format
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.
409
402
 
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.
413
 
 
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.
416
405
 
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.
420
410
    """
421
411
 
422
412
    takes_options = ['remember', 'overwrite', 'revision', 'verbose']
435
425
        reader = None
436
426
        if location is not None:
437
427
            try:
438
 
                reader = read_bundle_from_url(location)
 
428
                reader = bundle.read_bundle_from_url(location)
439
429
            except NotABundle:
440
430
                pass # Continue on considering this url a Branch
441
431
 
462
452
        rev_id = None
463
453
        if revision is None:
464
454
            if reader is not None:
465
 
                rev_id = reader.info.target
 
455
                rev_id = reader.target
466
456
        elif len(revision) == 1:
467
457
            rev_id = revision[0].in_history(branch_from).rev_id
468
458
        else:
506
496
 
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.
510
501
    """
511
502
 
512
503
    takes_options = ['remember', 'overwrite', 'verbose',
530
521
            else:
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
535
526
 
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)
540
529
 
541
530
        old_rh = []
542
531
        try:
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)
575
567
        else:
 
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()
577
573
            try:
578
574
                try:
618
614
 
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)
655
650
            try:
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.' %
662
657
                                      to_location)
663
658
            try:
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:
673
 
                rmtree(to_location)
 
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)
676
671
            if name:
710
705
                                 "such access, and also support local commits."
711
706
                            ),
712
707
                     ]
 
708
    aliases = ['co']
713
709
 
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)):
736
732
            try:
737
733
                source.bzrdir.open_workingtree()
738
734
            except errors.NoWorkingTree:
749
745
                                      to_location)
750
746
            else:
751
747
                raise
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())
754
750
        try:
755
751
            if lightweight:
756
752
                checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
757
 
                bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
 
753
                branch.BranchReferenceFormat().initialize(checkout, source)
758
754
            else:
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)
767
763
        finally:
768
 
            bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
 
764
            bzrdir.BzrDirFormat.set_default_format(old_format)
769
765
 
770
766
 
771
767
class cmd_renames(Command):
778
774
 
779
775
    @display_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()
784
 
 
785
 
        renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
 
781
        renames = list(find_renames(old_inv, new_inv))
786
782
        renames.sort()
787
783
        for old_name, new_name in renames:
788
784
            self.outf.write("%s => %s\n" % (old_name, new_name))
936
932
 
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)
940
936
        reconcile(dir)
941
937
 
942
938
 
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?']
 
942
 
945
943
    hidden = True
946
944
 
947
945
    @display_command
948
 
    def run(self):
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')
953
951
 
954
952
 
955
953
class cmd_ancestry(Command):
956
954
    """List all revisions merged into this branch."""
 
955
    takes_args = ['location?']
 
956
 
957
957
    hidden = True
958
958
 
959
959
    @display_command
960
 
    def run(self):
961
 
        tree = WorkingTree.open_containing(u'.')[0]
962
 
        b = tree.branch
963
 
        # FIXME. should be tree.last_revision
964
 
        revision_ids = b.repository.get_ancestry(b.last_revision())
 
960
    def run(self, location="."):
 
961
        try:
 
962
            wt = WorkingTree.open_containing(location)[0]
 
963
        except errors.NoWorkingTree:
 
964
            b = Branch.open(location)
 
965
            last_revision = b.last_revision()
 
966
        else:
 
967
            b = wt.branch
 
968
            last_revision = wt.last_revision()
 
969
 
 
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:
999
1005
                            type=get_format_type),
1000
1006
                     ]
1001
1007
    def run(self, location=None, format=None):
1002
 
        from bzrlib.branch import Branch
1003
1008
        if format is None:
1004
1009
            format = get_format_type('default')
1005
1010
        if location is None:
1204
1209
            if file_id in basis_inv:
1205
1210
                continue
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):
1208
1213
                continue
1209
1214
            self.outf.write(path + '\n')
1210
1215
 
1319
1324
            (rev2, rev1) = (rev1, rev2)
1320
1325
 
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, 
 
1329
                                        default=default)
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))
1367
1373
 
1368
1374
 
1424
1430
    """List unknown files."""
1425
1431
    @display_command
1426
1432
    def run(self):
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')
1430
1435
 
1431
1436
 
1432
1437
class cmd_ignore(Command):
1596
1601
    hidden = True    
1597
1602
    @display_command
1598
1603
    def run(self):
1599
 
        print bzrlib.osutils.local_time_offset()
 
1604
        print osutils.local_time_offset()
1600
1605
 
1601
1606
 
1602
1607
 
1680
1685
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1681
1686
 
1682
1687
        if message == "":
1683
 
                raise BzrCommandError("empty commit message specified")
 
1688
            raise BzrCommandError("empty commit message specified")
1684
1689
        
1685
1690
        if verbose:
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):
1780
1785
        try:
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()
1785
 
        
 
1788
            c = config.GlobalConfig()
1786
1789
        if email:
1787
 
            print config.user_email()
 
1790
            print c.user_email()
1788
1791
        else:
1789
 
            print config.username()
 
1792
            print c.username()
1790
1793
 
1791
1794
 
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])
1878
1881
        print
1879
 
        bzrlib.trace.info('running tests...')
 
1882
        info('running tests...')
1880
1883
        try:
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)
1884
1887
            else:
1899
1902
                              test_suite_factory=test_suite_factory,
1900
1903
                              lsprof_timed=lsprof_timed)
1901
1904
            if result:
1902
 
                bzrlib.trace.info('tests passed')
 
1905
                info('tests passed')
1903
1906
            else:
1904
 
                bzrlib.trace.info('tests failed')
 
1907
                info('tests failed')
1905
1908
            return int(not result)
1906
1909
        finally:
1907
 
            bzrlib.ui.ui_factory = save_ui
 
1910
            ui.ui_factory = save_ui
1908
1911
 
1909
1912
 
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
1916
1916
    
1917
1917
    try:
1918
 
        branch = Branch.open(dirname(abspath(dirname(__file__))))
 
1918
        branch = Branch.open(dirname(osutils.abspath(dirname(__file__))))
1919
1919
        return branch
1920
 
    except bzrlib.errors.BzrError:
 
1920
    except errors.BzrError:
1921
1921
        return None
1922
1922
    
1923
1923
 
1924
1924
def show_version():
 
1925
    import bzrlib
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)
1994
1995
 
1995
1996
        print 'merge base is revision %s' % base_rev_id
1996
 
        
1997
 
        return
1998
 
 
1999
 
        if base_revno is None:
2000
 
            raise bzrlib.errors.UnrelatedBranches()
2001
 
 
2002
 
        print ' r%-6d in %s' % (base_revno, branch)
2003
 
 
2004
 
        other_revno = branch2.revision_id_to_revno(base_revid)
2005
 
        
2006
 
        print ' r%-6d in %s' % (other_revno, other)
2007
 
 
2008
1997
 
2009
1998
 
2010
1999
class cmd_merge(Command):
2011
2000
    """Perform a three-way merge.
2012
2001
    
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
 
2006
    specified branch.
2018
2007
 
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
2029
2018
 
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.
2033
2023
 
2034
2024
    Examples:
2035
2025
 
2066
2056
 
2067
2057
        if branch is not None:
2068
2058
            try:
2069
 
                reader = read_bundle_from_url(branch)
 
2059
                reader = bundle.read_bundle_from_url(branch)
2070
2060
            except NotABundle:
2071
2061
                pass # Continue on considering this url a Branch
2072
2062
            else:
2106
2096
            interesting_files = [path]
2107
2097
        else:
2108
2098
            interesting_files = None
2109
 
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
2099
        pb = ui.ui_factory.nested_progress_bar()
2110
2100
        try:
2111
2101
            try:
2112
2102
                conflict_count = merge(other, base, check_clean=(not force),
2120
2110
                return 1
2121
2111
            else:
2122
2112
                return 0
2123
 
        except bzrlib.errors.AmbiguousBase, e:
 
2113
        except errors.AmbiguousBase, e:
2124
2114
            m = ("sorry, bzr can't determine the right merge base yet\n"
2125
2115
                 "candidates are:\n  "
2126
2116
                 + "\n  ".join(e.bases)
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"
2192
 
                                      + "multi-merges.")
 
2181
                                      " merges.  Not cherrypicking or"
 
2182
                                      " multi-merges.")
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')
2260
2250
        else:
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()
2263
2253
        try:
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)
2336
2325
                     'show-ids',
2337
2326
                     'verbose'
2338
2327
                     ]
 
2328
    encoding_type = 'replace'
2339
2329
 
 
2330
    @display_command
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()
2358
2349
            try:
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,
 
2356
                                   to_file=self.outf,
2364
2357
                                   show_ids=show_ids,
2365
2358
                                   show_timezone='original')
2366
2359
                if reverse is False:
2423
2416
 
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'
 
2421
                            ' testament')]
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
 
2426
        if strict is True:
 
2427
            testament_class = StrictTestament
 
2428
        else:
 
2429
            testament_class = Testament
2431
2430
        b = WorkingTree.open_containing(branch)[0].branch
2432
2431
        b.lock_read()
2433
2432
        try:
2435
2434
                rev_id = b.last_revision()
2436
2435
            else:
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)
2439
2438
            if long:
2440
2439
                sys.stdout.writelines(t.as_text_lines())
2441
2440
            else:
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']
2494
2493
    
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')
2562
2560
 
2563
2561
 
2564
 
class cmd_uncommit(bzrlib.commands.Command):
 
2562
class cmd_uncommit(Command):
2565
2563
    """Remove the last committed revision.
2566
2564
 
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
2590
2587
        import sys
2591
2588
        from bzrlib.uncommit import uncommit