/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: v.ladeuil+lp at free
  • Date: 2006-11-08 07:44:30 UTC
  • mfrom: (2123 +trunk)
  • mto: (2145.1.1 keepalive)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: v.ladeuil+lp@free.fr-20061108074430-a9c08d4a475bd97f
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import codecs
24
24
import errno
25
25
import sys
 
26
import tempfile
26
27
 
27
28
import bzrlib
28
29
from bzrlib import (
75
76
 
76
77
    :param file_list: Filenames to convert.  
77
78
 
78
 
    :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
 
80
        None.
79
81
 
80
82
    :return: workingtree, [relative_paths]
81
83
    """
82
84
    if file_list is None or len(file_list) == 0:
83
85
        return WorkingTree.open_containing(default_branch)[0], file_list
84
 
    tree = WorkingTree.open_containing(file_list[0])[0]
 
86
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
85
87
    new_list = []
86
88
    for filename in file_list:
87
89
        try:
88
 
            new_list.append(tree.relpath(filename))
 
90
            new_list.append(tree.relpath(osutils.dereference_path(filename)))
89
91
        except errors.PathNotChild:
90
92
            raise errors.FileInWrongBranch(tree.branch, filename)
91
93
    return tree, new_list
944
946
        tree, relpath = WorkingTree.open_containing(filename)
945
947
        i = tree.inventory.path2id(relpath)
946
948
        if i is None:
947
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
949
            raise errors.NotVersionedError(filename)
948
950
        else:
949
951
            self.outf.write(i + '\n')
950
952
 
965
967
        inv = tree.inventory
966
968
        fid = inv.path2id(relpath)
967
969
        if fid is None:
968
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
970
            raise errors.NotVersionedError(filename)
969
971
        for fip in inv.get_idpath(fid):
970
972
            self.outf.write(fip + '\n')
971
973
 
1196
1198
            new_label = 'new/'
1197
1199
        else:
1198
1200
            if not ':' in prefix:
1199
 
                 raise errors.BzrError("--diff-prefix expects two values"
1200
 
                                       " separated by a colon")
 
1201
                 raise BzrCommandError(
 
1202
                     "--diff-prefix expects two values separated by a colon")
1201
1203
            old_label, new_label = prefix.split(":")
1202
1204
        
1203
1205
        try:
1380
1382
                    # either no tree, or is remote.
1381
1383
                    inv = b.basis_tree().inventory
1382
1384
                file_id = inv.path2id(fp)
 
1385
                if file_id is None:
 
1386
                    raise errors.BzrCommandError(
 
1387
                        "Path does not have any revision history: %s" %
 
1388
                        location)
1383
1389
        else:
1384
1390
            # local dir only
1385
1391
            # FIXME ? log the current subdir only RBC 20060203 
1535
1541
 
1536
1542
 
1537
1543
class cmd_ignore(Command):
1538
 
    """Ignore a command or pattern.
 
1544
    """Ignore specified files or patterns.
1539
1545
 
1540
1546
    To remove patterns from the ignore list, edit the .bzrignore file.
1541
1547
 
 
1548
    Trailing slashes on patterns are ignored. 
1542
1549
    If the pattern contains a slash, it is compared to the whole path
1543
1550
    from the branch root.  Otherwise, it is compared to only the last
1544
1551
    component of the path.  To match a file only in the root directory,
1545
1552
    prepend './'.
1546
1553
 
 
1554
    Ignore patterns specifying absolute paths are not allowed.
 
1555
 
1547
1556
    Ignore patterns are case-insensitive on case-insensitive systems.
1548
1557
 
1549
1558
    Note: wildcards must be quoted from the shell on Unix.
1552
1561
        bzr ignore ./Makefile
1553
1562
        bzr ignore '*.class'
1554
1563
    """
1555
 
    # TODO: Complain if the filename is absolute
1556
 
    takes_args = ['name_pattern?']
 
1564
    takes_args = ['name_pattern*']
1557
1565
    takes_options = [
1558
1566
                     Option('old-default-rules',
1559
1567
                            help='Out the ignore rules bzr < 0.9 always used.')
1560
1568
                     ]
1561
1569
    
1562
 
    def run(self, name_pattern=None, old_default_rules=None):
 
1570
    def run(self, name_pattern_list=None, old_default_rules=None):
1563
1571
        from bzrlib.atomicfile import AtomicFile
1564
1572
        if old_default_rules is not None:
1565
1573
            # dump the rules and exit
1566
1574
            for pattern in ignores.OLD_DEFAULTS:
1567
1575
                print pattern
1568
1576
            return
1569
 
        if name_pattern is None:
1570
 
            raise errors.BzrCommandError("ignore requires a NAME_PATTERN")
 
1577
        if not name_pattern_list:
 
1578
            raise errors.BzrCommandError("ignore requires at least one "
 
1579
                                  "NAME_PATTERN or --old-default-rules")
 
1580
        for name_pattern in name_pattern_list:
 
1581
            if name_pattern[0] == '/':
 
1582
                raise errors.BzrCommandError(
 
1583
                    "NAME_PATTERN should not be an absolute path")
1571
1584
        tree, relpath = WorkingTree.open_containing(u'.')
1572
1585
        ifn = tree.abspath('.bzrignore')
1573
1586
        if os.path.exists(ifn):
1584
1597
 
1585
1598
        if igns and igns[-1] != '\n':
1586
1599
            igns += '\n'
1587
 
        igns += name_pattern + '\n'
 
1600
        for name_pattern in name_pattern_list:
 
1601
            igns += name_pattern.rstrip('/') + '\n'
1588
1602
 
1589
 
        f = AtomicFile(ifn, 'wt')
 
1603
        f = AtomicFile(ifn, 'wb')
1590
1604
        try:
1591
1605
            f.write(igns.encode('utf-8'))
1592
1606
            f.commit()
1647
1661
    Root may be the top directory for tar, tgz and tbz2 formats. If none
1648
1662
    is given, the top directory will be the root name of the file.
1649
1663
 
 
1664
    If branch is omitted then the branch containing the CWD will be used.
 
1665
 
1650
1666
    Note: export of tree with non-ascii filenames to zip is not supported.
1651
1667
 
1652
1668
     Supported formats       Autodetected by extension
1657
1673
         tgz                      .tar.gz, .tgz
1658
1674
         zip                          .zip
1659
1675
    """
1660
 
    takes_args = ['dest']
 
1676
    takes_args = ['dest', 'branch?']
1661
1677
    takes_options = ['revision', 'format', 'root']
1662
 
    def run(self, dest, revision=None, format=None, root=None):
 
1678
    def run(self, dest, branch=None, revision=None, format=None, root=None):
1663
1679
        from bzrlib.export import export
1664
 
        tree = WorkingTree.open_containing(u'.')[0]
1665
 
        b = tree.branch
 
1680
 
 
1681
        if branch is None:
 
1682
            tree = WorkingTree.open_containing(u'.')[0]
 
1683
            b = tree.branch
 
1684
        else:
 
1685
            b = Branch.open(branch)
 
1686
            
1666
1687
        if revision is None:
1667
1688
            # should be tree.last_revision  FIXME
1668
1689
            rev_id = b.last_revision()
1669
1690
        else:
1670
1691
            if len(revision) != 1:
1671
 
                raise errors.BzrError('bzr export --revision takes exactly'
1672
 
                                      ' 1 argument')
 
1692
                raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1673
1693
            rev_id = revision[0].in_history(b).rev_id
1674
1694
        t = b.repository.revision_tree(rev_id)
1675
1695
        try:
1681
1701
class cmd_cat(Command):
1682
1702
    """Write a file's text from a previous revision."""
1683
1703
 
1684
 
    takes_options = ['revision']
 
1704
    takes_options = ['revision', 'name-from-revision']
1685
1705
    takes_args = ['filename']
1686
1706
 
1687
1707
    @display_command
1688
 
    def run(self, filename, revision=None):
 
1708
    def run(self, filename, revision=None, name_from_revision=False):
1689
1709
        if revision is not None and len(revision) != 1:
1690
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly one number")
 
1710
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
 
1711
                                        " one number")
 
1712
 
1691
1713
        tree = None
1692
1714
        try:
1693
1715
            tree, relpath = WorkingTree.open_containing(filename)
1703
1725
            revision_id = b.last_revision()
1704
1726
        else:
1705
1727
            revision_id = revision[0].in_history(b).rev_id
1706
 
        b.print_file(relpath, revision_id)
 
1728
 
 
1729
        cur_file_id = tree.path2id(relpath)
 
1730
        rev_tree = b.repository.revision_tree(revision_id)
 
1731
        old_file_id = rev_tree.path2id(relpath)
 
1732
        
 
1733
        if name_from_revision:
 
1734
            if old_file_id is None:
 
1735
                raise errors.BzrCommandError("%r is not present in revision %s"
 
1736
                                                % (filename, revision_id))
 
1737
            else:
 
1738
                rev_tree.print_file(old_file_id)
 
1739
        elif cur_file_id is not None:
 
1740
            rev_tree.print_file(cur_file_id)
 
1741
        elif old_file_id is not None:
 
1742
            rev_tree.print_file(old_file_id)
 
1743
        else:
 
1744
            raise errors.BzrCommandError("%r is not present in revision %s" %
 
1745
                                         (filename, revision_id))
1707
1746
 
1708
1747
 
1709
1748
class cmd_local_time_offset(Command):
1763
1802
                StrictCommitFailed)
1764
1803
        from bzrlib.msgeditor import edit_commit_message, \
1765
1804
                make_commit_message_template
1766
 
        from tempfile import TemporaryFile
1767
1805
 
1768
1806
        # TODO: Need a blackbox test for invoking the external editor; may be
1769
1807
        # slightly problematic to run this cross-platform.
1770
1808
 
1771
1809
        # TODO: do more checks that the commit will succeed before 
1772
1810
        # spending the user's valuable time typing a commit message.
1773
 
        #
1774
 
        # TODO: if the commit *does* happen to fail, then save the commit 
1775
 
        # message to a temporary file where it can be recovered
1776
1811
        tree, selected_list = tree_files(selected_list)
1777
1812
        if selected_list == ['']:
1778
1813
            # workaround - commit of root of tree should be exactly the same
1801
1836
            reporter = ReportCommitToLog()
1802
1837
        else:
1803
1838
            reporter = NullCommitReporter()
1804
 
        
 
1839
 
 
1840
        msgfilename = self._save_commit_message(message, tree.basedir)
1805
1841
        try:
1806
1842
            tree.commit(message, specific_files=selected_list,
1807
1843
                        allow_pointless=unchanged, strict=strict, local=local,
1808
1844
                        reporter=reporter)
 
1845
            if msgfilename is not None:
 
1846
                try:
 
1847
                    os.unlink(msgfilename)
 
1848
                except IOError, e:
 
1849
                    warning("failed to unlink %s: %s; ignored", msgfilename, e)
1809
1850
        except PointlessCommit:
1810
1851
            # FIXME: This should really happen before the file is read in;
1811
1852
            # perhaps prepare the commit; get the message; then actually commit
1812
 
            raise errors.BzrCommandError("no changes to commit."
1813
 
                                         " use --unchanged to commit anyhow")
 
1853
            if msgfilename is not None:
 
1854
                raise errors.BzrCommandError("no changes to commit."
 
1855
                                  " use --unchanged to commit anyhow\n"
 
1856
                                  "Commit message saved. To reuse the message,"
 
1857
                                  " do\nbzr commit --file " + msgfilename)
 
1858
            else:
 
1859
                raise errors.BzrCommandError("no changes to commit."
 
1860
                                  " use --unchanged to commit anyhow")
1814
1861
        except ConflictsInTree:
1815
 
            raise errors.BzrCommandError("Conflicts detected in working tree.  "
1816
 
                'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
 
1862
            if msgfilename is not None:
 
1863
                raise errors.BzrCommandError('Conflicts detected in working '
 
1864
                    'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
 
1865
                    ' resolve.\n'
 
1866
                    'Commit message saved. To reuse the message,'
 
1867
                    ' do\nbzr commit --file ' + msgfilename)
 
1868
            else:
 
1869
                raise errors.BzrCommandError('Conflicts detected in working '
 
1870
                    'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
 
1871
                    ' resolve.')
1817
1872
        except StrictCommitFailed:
1818
 
            raise errors.BzrCommandError("Commit refused because there are unknown "
1819
 
                                         "files in the working tree.")
 
1873
            if msgfilename is not None:
 
1874
                raise errors.BzrCommandError("Commit refused because there are"
 
1875
                                  " unknown files in the working tree.\n"
 
1876
                                  "Commit message saved. To reuse the message,"
 
1877
                                  " do\nbzr commit --file " + msgfilename)
 
1878
            else:
 
1879
                raise errors.BzrCommandError("Commit refused because there are"
 
1880
                                  " unknown files in the working tree.")
1820
1881
        except errors.BoundBranchOutOfDate, e:
1821
 
            raise errors.BzrCommandError(str(e) + "\n"
 
1882
            if msgfilename is not None:
 
1883
                raise errors.BzrCommandError(str(e) + "\n"
 
1884
                'To commit to master branch, run update and then commit.\n'
 
1885
                'You can also pass --local to commit to continue working '
 
1886
                'disconnected.\n'
 
1887
                'Commit message saved. To reuse the message,'
 
1888
                ' do\nbzr commit --file ' + msgfilename)
 
1889
            else:
 
1890
                raise errors.BzrCommandError(str(e) + "\n"
1822
1891
                'To commit to master branch, run update and then commit.\n'
1823
1892
                'You can also pass --local to commit to continue working '
1824
1893
                'disconnected.')
1825
1894
 
 
1895
    def _save_commit_message(self, message, basedir):
 
1896
        # save the commit message and only unlink it if the commit was
 
1897
        # successful
 
1898
        msgfilename = None
 
1899
        try:
 
1900
            tmp_fileno, msgfilename = tempfile.mkstemp(prefix='bzr-commit-',
 
1901
                                                       dir=basedir)
 
1902
        except OSError:
 
1903
            try:
 
1904
                # No access to working dir, try $TMP
 
1905
                tmp_fileno, msgfilename = tempfile.mkstemp(prefix='bzr-commit-')
 
1906
            except OSError:
 
1907
                # We can't create a temp file, try to work without it
 
1908
                return None
 
1909
        try:
 
1910
            os.write(tmp_fileno, message.encode(bzrlib.user_encoding, 'replace'))
 
1911
        finally:
 
1912
            os.close(tmp_fileno)
 
1913
        return msgfilename
 
1914
 
 
1915
 
1826
1916
class cmd_check(Command):
1827
1917
    """Validate consistency of branch history.
1828
1918
 
1842
1932
        check(branch, verbose)
1843
1933
 
1844
1934
 
1845
 
class cmd_scan_cache(Command):
1846
 
    hidden = True
1847
 
    def run(self):
1848
 
        from bzrlib.hashcache import HashCache
1849
 
 
1850
 
        c = HashCache(u'.')
1851
 
        c.read()
1852
 
        c.scan()
1853
 
            
1854
 
        print '%6d stats' % c.stat_count
1855
 
        print '%6d in hashcache' % len(c._cache)
1856
 
        print '%6d files removed from cache' % c.removed_count
1857
 
        print '%6d hashes updated' % c.update_count
1858
 
        print '%6d files changed too recently to cache' % c.danger_count
1859
 
 
1860
 
        if c.needs_write:
1861
 
            c.write()
1862
 
 
1863
 
 
1864
1935
class cmd_upgrade(Command):
1865
1936
    """Upgrade branch storage to current format.
1866
1937
 
2018
2089
 
2019
2090
        if cache_dir is not None:
2020
2091
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2021
 
        # we don't want progress meters from the tests to go to the
2022
 
        # real output; and we don't want log messages cluttering up
2023
 
        # the real logs.
2024
 
        save_ui = ui.ui_factory
2025
2092
        print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2026
2093
        print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2027
2094
        print
2028
 
        info('running tests...')
 
2095
        if testspecs_list is not None:
 
2096
            pattern = '|'.join(testspecs_list)
 
2097
        else:
 
2098
            pattern = ".*"
 
2099
        if benchmark:
 
2100
            test_suite_factory = benchmarks.test_suite
 
2101
            if verbose is None:
 
2102
                verbose = True
 
2103
            # TODO: should possibly lock the history file...
 
2104
            benchfile = open(".perf_history", "at")
 
2105
        else:
 
2106
            test_suite_factory = None
 
2107
            if verbose is None:
 
2108
                verbose = False
 
2109
            benchfile = None
2029
2110
        try:
2030
 
            ui.ui_factory = ui.SilentUIFactory()
2031
 
            if testspecs_list is not None:
2032
 
                pattern = '|'.join(testspecs_list)
2033
 
            else:
2034
 
                pattern = ".*"
2035
 
            if benchmark:
2036
 
                test_suite_factory = benchmarks.test_suite
2037
 
                if verbose is None:
2038
 
                    verbose = True
2039
 
                # TODO: should possibly lock the history file...
2040
 
                benchfile = open(".perf_history", "at")
2041
 
            else:
2042
 
                test_suite_factory = None
2043
 
                if verbose is None:
2044
 
                    verbose = False
2045
 
                benchfile = None
2046
 
            try:
2047
 
                result = selftest(verbose=verbose, 
2048
 
                                  pattern=pattern,
2049
 
                                  stop_on_failure=one, 
2050
 
                                  keep_output=keep_output,
2051
 
                                  transport=transport,
2052
 
                                  test_suite_factory=test_suite_factory,
2053
 
                                  lsprof_timed=lsprof_timed,
2054
 
                                  bench_history=benchfile)
2055
 
            finally:
2056
 
                if benchfile is not None:
2057
 
                    benchfile.close()
2058
 
            if result:
2059
 
                info('tests passed')
2060
 
            else:
2061
 
                info('tests failed')
2062
 
            return int(not result)
 
2111
            result = selftest(verbose=verbose, 
 
2112
                              pattern=pattern,
 
2113
                              stop_on_failure=one, 
 
2114
                              keep_output=keep_output,
 
2115
                              transport=transport,
 
2116
                              test_suite_factory=test_suite_factory,
 
2117
                              lsprof_timed=lsprof_timed,
 
2118
                              bench_history=benchfile)
2063
2119
        finally:
2064
 
            ui.ui_factory = save_ui
 
2120
            if benchfile is not None:
 
2121
                benchfile.close()
 
2122
        if result:
 
2123
            info('tests passed')
 
2124
        else:
 
2125
            info('tests failed')
 
2126
        return int(not result)
2065
2127
 
2066
2128
 
2067
2129
class cmd_version(Command):
2412
2474
 
2413
2475
class cmd_assert_fail(Command):
2414
2476
    """Test reporting of assertion failures"""
 
2477
    # intended just for use in testing
 
2478
 
2415
2479
    hidden = True
 
2480
 
2416
2481
    def run(self):
2417
 
        assert False, "always fails"
 
2482
        raise AssertionError("always fails")
2418
2483
 
2419
2484
 
2420
2485
class cmd_help(Command):