~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Martin Pool
  • Date: 2006-01-30 06:23:50 UTC
  • mfrom: (1534.1.17 integration)
  • Revision ID: mbp@sourcefrog.net-20060130062350-d6f25277ddcdfd79
[merge] robert's integration of much recent work

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
19
 
# DO NOT change this to cStringIO - it results in control files 
20
 
# written as UCS4
21
 
# FIXIT! (Only deal with byte streams OR unicode at any one layer.)
22
 
# RBC 20051018
23
19
 
24
 
from StringIO import StringIO
 
20
import os
25
21
import sys
26
 
import os
27
22
 
28
23
import bzrlib
29
24
from bzrlib import BZRDIR
 
25
from bzrlib._merge_core import ApplyMerge3
30
26
from bzrlib.commands import Command, display_command
31
27
from bzrlib.branch import Branch
32
28
from bzrlib.revision import common_ancestor
148
144
            raise BzrCommandError('You must supply either --revision or a revision_id')
149
145
        b = WorkingTree.open_containing(u'.')[0].branch
150
146
        if revision_id is not None:
151
 
            sys.stdout.write(b.get_revision_xml(revision_id))
 
147
            sys.stdout.write(b.repository.get_revision_xml(revision_id))
152
148
        elif revision is not None:
153
149
            for rev in revision:
154
150
                if rev is None:
155
151
                    raise BzrCommandError('You cannot specify a NULL revision.')
156
152
                revno, rev_id = rev.in_history(b)
157
 
                sys.stdout.write(b.get_revision_xml(rev_id))
 
153
                sys.stdout.write(b.repository.get_revision_xml(rev_id))
158
154
    
159
155
 
160
156
class cmd_revno(Command):
298
294
            if len(revision) > 1:
299
295
                raise BzrCommandError('bzr inventory --revision takes'
300
296
                    ' exactly one revision identifier')
301
 
            inv = tree.branch.get_revision_inventory(
 
297
            inv = tree.branch.repository.get_revision_inventory(
302
298
                revision[0].in_history(tree.branch).rev_id)
303
299
 
304
300
        for path, entry in inv.entries():
399
395
    takes_args = ['location?']
400
396
 
401
397
    def run(self, location=None, remember=False, overwrite=False, verbose=False):
402
 
        from bzrlib.merge import merge
403
398
        from shutil import rmtree
404
399
        import errno
405
400
        # FIXME: too much stuff is in the command class        
548
543
    aliases = ['get', 'clone']
549
544
 
550
545
    def run(self, from_location, to_location=None, revision=None, basis=None):
551
 
        from bzrlib.clone import copy_branch
552
546
        import errno
553
547
        from shutil import rmtree
554
548
        if revision is None:
591
585
                else:
592
586
                    raise
593
587
            try:
594
 
                copy_branch(br_from, to_location, revision_id, basis_branch)
 
588
                br_from.clone(to_location, revision_id, basis_branch)
595
589
            except bzrlib.errors.NoSuchRevision:
596
590
                rmtree(to_location)
597
591
                msg = "The branch %s has no revision %s." % (from_location, revision[0])
602
596
                raise BzrCommandError(msg)
603
597
            branch = Branch.open(to_location)
604
598
            if name:
605
 
                name = StringIO(name)
606
 
                branch.put_controlfile('branch-name', name)
 
599
                branch.control_files.put_utf8('branch-name', name)
 
600
 
607
601
            note('Branched %d revision(s).' % branch.revno())
608
602
        finally:
609
603
            br_from.unlock()
927
921
            if tree is None:
928
922
                b, fp = Branch.open_containing(filename)
929
923
                if fp != '':
930
 
                    inv = b.get_inventory(b.last_revision())
 
924
                    inv = b.repository.get_inventory(b.last_revision())
931
925
            if fp != '':
932
926
                file_id = inv.path2id(fp)
933
927
            else:
1036
1030
        elif relpath:
1037
1031
            relpath += '/'
1038
1032
        if revision is not None:
1039
 
            tree = tree.branch.revision_tree(
 
1033
            tree = tree.branch.repository.revision_tree(
1040
1034
                revision[0].in_history(tree.branch).rev_id)
1041
1035
        for fp, fc, kind, fid, entry in tree.list_files():
1042
1036
            if fp.startswith(relpath):
1194
1188
            if len(revision) != 1:
1195
1189
                raise BzrError('bzr export --revision takes exactly 1 argument')
1196
1190
            rev_id = revision[0].in_history(b).rev_id
1197
 
        t = b.revision_tree(rev_id)
 
1191
        t = b.repository.revision_tree(rev_id)
1198
1192
        try:
1199
1193
            export(t, dest, format, root)
1200
1194
        except errors.NoSuchExportFormat, e:
1582
1576
 
1583
1577
    def run(self, branch=None, revision=None, force=False, merge_type=None,
1584
1578
            show_base=False, reprocess=False):
1585
 
        from bzrlib.merge import merge
1586
 
        from bzrlib.merge_core import ApplyMerge3
 
1579
        from bzrlib._merge_core import ApplyMerge3
1587
1580
        if merge_type is None:
1588
1581
            merge_type = ApplyMerge3
1589
1582
        if branch is None:
1640
1633
    def run(self, file_list=None, merge_type=None, show_base=False,
1641
1634
            reprocess=False):
1642
1635
        from bzrlib.merge import merge_inner, transform_tree
1643
 
        from bzrlib.merge_core import ApplyMerge3
 
1636
        from bzrlib._merge_core import ApplyMerge3
1644
1637
        if merge_type is None:
1645
1638
            merge_type = ApplyMerge3
1646
1639
        tree, file_list = tree_files(file_list)
1651
1644
                raise BzrCommandError("Sorry, remerge only works after normal"
1652
1645
                                      + " merges.  Not cherrypicking or"
1653
1646
                                      + "multi-merges.")
 
1647
            repository = tree.branch.repository
1654
1648
            base_revision = common_ancestor(tree.branch.last_revision(), 
1655
 
                                            pending_merges[0], tree.branch)
1656
 
            base_tree = tree.branch.revision_tree(base_revision)
1657
 
            other_tree = tree.branch.revision_tree(pending_merges[0])
 
1649
                                            pending_merges[0], repository)
 
1650
            base_tree = repository.revision_tree(base_revision)
 
1651
            other_tree = repository.revision_tree(pending_merges[0])
1658
1652
            interesting_ids = None
1659
1653
            if file_list is not None:
1660
1654
                interesting_ids = set()
1701
1695
    aliases = ['merge-revert']
1702
1696
 
1703
1697
    def run(self, revision=None, no_backup=False, file_list=None):
1704
 
        from bzrlib.merge import merge_inner
1705
1698
        from bzrlib.commands import parse_spec
1706
1699
        if file_list is not None:
1707
1700
            if len(file_list) == 0:
1708
1701
                raise BzrCommandError("No files specified")
1709
1702
        else:
1710
1703
            file_list = []
 
1704
        
 
1705
        tree, file_list = tree_files(file_list)
1711
1706
        if revision is None:
1712
 
            revno = -1
1713
 
            tree = WorkingTree.open_containing(u'.')[0]
1714
1707
            # FIXME should be tree.last_revision
1715
1708
            rev_id = tree.branch.last_revision()
1716
1709
        elif len(revision) != 1:
1717
1710
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1718
1711
        else:
1719
 
            tree, file_list = tree_files(file_list)
1720
1712
            rev_id = revision[0].in_history(tree.branch).rev_id
1721
 
        tree.revert(file_list, tree.branch.revision_tree(rev_id),
1722
 
                                not no_backup)
 
1713
        tree.revert(file_list, tree.branch.repository.revision_tree(rev_id),
 
1714
                    not no_backup)
1723
1715
 
1724
1716
 
1725
1717
class cmd_assert_fail(Command):
1770
1762
        from bzrlib.branch import Branch
1771
1763
        from_b = Branch.open(from_branch)
1772
1764
        to_b = Branch.open(to_branch)
1773
 
        from_b.lock_read()
1774
 
        try:
1775
 
            to_b.lock_write()
1776
 
            try:
1777
 
                Fetcher(to_b, from_b)
1778
 
            finally:
1779
 
                to_b.unlock()
1780
 
        finally:
1781
 
            from_b.unlock()
 
1765
        Fetcher(to_b, from_b)
1782
1766
 
1783
1767
 
1784
1768
class cmd_missing(Command):
1821
1805
            remote_extra.reverse()
1822
1806
        if local_extra and not theirs_only:
1823
1807
            print "You have %d extra revision(s):" % len(local_extra)
1824
 
            for data in iter_log_data(local_extra, local_branch, verbose):
 
1808
            for data in iter_log_data(local_extra, local_branch.repository,
 
1809
                                      verbose):
1825
1810
                lf.show(*data)
1826
1811
            printed_local = True
1827
1812
        else:
1830
1815
            if printed_local is True:
1831
1816
                print "\n\n"
1832
1817
            print "You are missing %d revision(s):" % len(remote_extra)
1833
 
            for data in iter_log_data(remote_extra, remote_branch, verbose):
 
1818
            for data in iter_log_data(remote_extra, remote_branch.repository, 
 
1819
                                      verbose):
1834
1820
                lf.show(*data)
1835
1821
        if not remote_extra and not local_extra:
1836
1822
            status_code = 0
1876
1862
                rev_id = b.last_revision()
1877
1863
            else:
1878
1864
                rev_id = revision[0].in_history(b).rev_id
1879
 
            t = Testament.from_revision(b, rev_id)
 
1865
            t = Testament.from_revision(b.repository, rev_id)
1880
1866
            if long:
1881
1867
                sys.stdout.writelines(t.as_text_lines())
1882
1868
            else:
1912
1898
        branch.lock_read()
1913
1899
        try:
1914
1900
            file_id = tree.inventory.path2id(relpath)
1915
 
            tree = branch.revision_tree(branch.last_revision())
 
1901
            tree = branch.repository.revision_tree(branch.last_revision())
1916
1902
            file_version = tree.inventory[file_id].revision
1917
1903
            annotate_file(branch, file_version, file_id, long, all, sys.stdout)
1918
1904
        finally:
1937
1923
        b = WorkingTree.open_containing(u'.')[0].branch
1938
1924
        gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
1939
1925
        if revision_id is not None:
1940
 
            b.sign_revision(revision_id, gpg_strategy)
 
1926
            b.repository.sign_revision(revision_id, gpg_strategy)
1941
1927
        elif revision is not None:
1942
1928
            if len(revision) == 1:
1943
1929
                revno, rev_id = revision[0].in_history(b)
1944
 
                b.sign_revision(rev_id, gpg_strategy)
 
1930
                b.repository.sign_revision(rev_id, gpg_strategy)
1945
1931
            elif len(revision) == 2:
1946
1932
                # are they both on rh- if so we can walk between them
1947
1933
                # might be nice to have a range helper for arbitrary
1953
1939
                if from_revno is None or to_revno is None:
1954
1940
                    raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
1955
1941
                for revno in range(from_revno, to_revno + 1):
1956
 
                    b.sign_revision(b.get_rev_id(revno), gpg_strategy)
 
1942
                    b.repository.sign_revision(b.get_rev_id(revno), 
 
1943
                                               gpg_strategy)
1957
1944
            else:
1958
1945
                raise BzrCommandError('Please supply either one revision, or a range.')
1959
1946
 
2006
1993
        for r in range(revno, b.revno()+1):
2007
1994
            rev_id = b.get_rev_id(r)
2008
1995
            lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
2009
 
            lf.show(r, b.get_revision(rev_id), None)
 
1996
            lf.show(r, b.repository.get_revision(rev_id), None)
2010
1997
 
2011
1998
        if dry_run:
2012
1999
            print 'Dry-run, pretending to remove the above revisions.'
2024
2011
                revno=revno)
2025
2012
 
2026
2013
 
 
2014
def merge(other_revision, base_revision,
 
2015
          check_clean=True, ignore_zero=False,
 
2016
          this_dir=None, backup_files=False, merge_type=ApplyMerge3,
 
2017
          file_list=None, show_base=False, reprocess=False):
 
2018
    """Merge changes into a tree.
 
2019
 
 
2020
    base_revision
 
2021
        list(path, revno) Base for three-way merge.  
 
2022
        If [None, None] then a base will be automatically determined.
 
2023
    other_revision
 
2024
        list(path, revno) Other revision for three-way merge.
 
2025
    this_dir
 
2026
        Directory to merge changes into; '.' by default.
 
2027
    check_clean
 
2028
        If true, this_dir must have no uncommitted changes before the
 
2029
        merge begins.
 
2030
    ignore_zero - If true, suppress the "zero conflicts" message when 
 
2031
        there are no conflicts; should be set when doing something we expect
 
2032
        to complete perfectly.
 
2033
    file_list - If supplied, merge only changes to selected files.
 
2034
 
 
2035
    All available ancestors of other_revision and base_revision are
 
2036
    automatically pulled into the branch.
 
2037
 
 
2038
    The revno may be -1 to indicate the last revision on the branch, which is
 
2039
    the typical case.
 
2040
 
 
2041
    This function is intended for use from the command line; programmatic
 
2042
    clients might prefer to call merge.merge_inner(), which has less magic 
 
2043
    behavior.
 
2044
    """
 
2045
    from bzrlib.merge import Merger, _MergeConflictHandler
 
2046
    if this_dir is None:
 
2047
        this_dir = u'.'
 
2048
    this_branch = Branch.open_containing(this_dir)[0]
 
2049
    if show_base and not merge_type is ApplyMerge3:
 
2050
        raise BzrCommandError("Show-base is not supported for this merge"
 
2051
                              " type. %s" % merge_type)
 
2052
    if reprocess and not merge_type is ApplyMerge3:
 
2053
        raise BzrCommandError("Reprocess is not supported for this merge"
 
2054
                              " type. %s" % merge_type)
 
2055
    if reprocess and show_base:
 
2056
        raise BzrCommandError("Cannot reprocess and show base.")
 
2057
    merger = Merger(this_branch)
 
2058
    merger.check_basis(check_clean)
 
2059
    merger.set_other(other_revision)
 
2060
    merger.set_base(base_revision)
 
2061
    if merger.base_rev_id == merger.other_rev_id:
 
2062
        note('Nothing to do.')
 
2063
        return 0
 
2064
    merger.backup_files = backup_files
 
2065
    merger.merge_type = merge_type 
 
2066
    merger.set_interesting_files(file_list)
 
2067
    merger.show_base = show_base 
 
2068
    merger.reprocess = reprocess
 
2069
    merger.conflict_handler = _MergeConflictHandler(merger.this_tree, 
 
2070
                                                    merger.base_tree, 
 
2071
                                                    merger.other_tree,
 
2072
                                                    ignore_zero=ignore_zero)
 
2073
    conflicts = merger.do_merge()
 
2074
    merger.set_pending()
 
2075
    return conflicts
 
2076
 
 
2077
 
2027
2078
# these get imported and then picked up by the scan for cmd_*
2028
2079
# TODO: Some more consistent way to split command definitions across files;
2029
2080
# we do need to load at least some information about them to know of