/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

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
211
213
                self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
212
214
    
213
215
 
 
216
class cmd_remove_tree(Command):
 
217
    """Remove the working tree from a given branch/checkout.
 
218
 
 
219
    Since a lightweight checkout is little more than a working tree
 
220
    this will refuse to run against one.
 
221
    """
 
222
 
 
223
    hidden = True
 
224
 
 
225
    takes_args = ['location?']
 
226
 
 
227
    def run(self, location='.'):
 
228
        d = bzrdir.BzrDir.open(location)
 
229
        
 
230
        try:
 
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 "
 
236
                                         "remote path")
 
237
        
 
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")
 
243
        
 
244
        d.destroy_workingtree()
 
245
        
 
246
 
214
247
class cmd_revno(Command):
215
248
    """Show current revision number.
216
249
 
944
977
        tree, relpath = WorkingTree.open_containing(filename)
945
978
        i = tree.inventory.path2id(relpath)
946
979
        if i is None:
947
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
980
            raise errors.NotVersionedError(filename)
948
981
        else:
949
982
            self.outf.write(i + '\n')
950
983
 
965
998
        inv = tree.inventory
966
999
        fid = inv.path2id(relpath)
967
1000
        if fid is None:
968
 
            raise errors.BzrError("%r is not a versioned file" % filename)
 
1001
            raise errors.NotVersionedError(filename)
969
1002
        for fip in inv.get_idpath(fid):
970
1003
            self.outf.write(fip + '\n')
971
1004
 
1196
1229
            new_label = 'new/'
1197
1230
        else:
1198
1231
            if not ':' in prefix:
1199
 
                 raise errors.BzrError("--diff-prefix expects two values"
1200
 
                                       " separated by a colon")
 
1232
                 raise BzrCommandError(
 
1233
                     "--diff-prefix expects two values separated by a colon")
1201
1234
            old_label, new_label = prefix.split(":")
1202
1235
        
1203
1236
        try:
1380
1413
                    # either no tree, or is remote.
1381
1414
                    inv = b.basis_tree().inventory
1382
1415
                file_id = inv.path2id(fp)
 
1416
                if file_id is None:
 
1417
                    raise errors.BzrCommandError(
 
1418
                        "Path does not have any revision history: %s" %
 
1419
                        location)
1383
1420
        else:
1384
1421
            # local dir only
1385
1422
            # FIXME ? log the current subdir only RBC 20060203 
1535
1572
 
1536
1573
 
1537
1574
class cmd_ignore(Command):
1538
 
    """Ignore a command or pattern.
 
1575
    """Ignore specified files or patterns.
1539
1576
 
1540
1577
    To remove patterns from the ignore list, edit the .bzrignore file.
1541
1578
 
 
1579
    Trailing slashes on patterns are ignored. 
1542
1580
    If the pattern contains a slash, it is compared to the whole path
1543
1581
    from the branch root.  Otherwise, it is compared to only the last
1544
1582
    component of the path.  To match a file only in the root directory,
1545
1583
    prepend './'.
1546
1584
 
 
1585
    Ignore patterns specifying absolute paths are not allowed.
 
1586
 
1547
1587
    Ignore patterns are case-insensitive on case-insensitive systems.
1548
1588
 
1549
1589
    Note: wildcards must be quoted from the shell on Unix.
1552
1592
        bzr ignore ./Makefile
1553
1593
        bzr ignore '*.class'
1554
1594
    """
1555
 
    # TODO: Complain if the filename is absolute
1556
 
    takes_args = ['name_pattern?']
 
1595
    takes_args = ['name_pattern*']
1557
1596
    takes_options = [
1558
1597
                     Option('old-default-rules',
1559
1598
                            help='Out the ignore rules bzr < 0.9 always used.')
1560
1599
                     ]
1561
1600
    
1562
 
    def run(self, name_pattern=None, old_default_rules=None):
 
1601
    def run(self, name_pattern_list=None, old_default_rules=None):
1563
1602
        from bzrlib.atomicfile import AtomicFile
1564
1603
        if old_default_rules is not None:
1565
1604
            # dump the rules and exit
1566
1605
            for pattern in ignores.OLD_DEFAULTS:
1567
1606
                print pattern
1568
1607
            return
1569
 
        if name_pattern is None:
1570
 
            raise errors.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")
1571
1615
        tree, relpath = WorkingTree.open_containing(u'.')
1572
1616
        ifn = tree.abspath('.bzrignore')
1573
1617
        if os.path.exists(ifn):
1584
1628
 
1585
1629
        if igns and igns[-1] != '\n':
1586
1630
            igns += '\n'
1587
 
        igns += name_pattern + '\n'
 
1631
        for name_pattern in name_pattern_list:
 
1632
            igns += name_pattern.rstrip('/') + '\n'
1588
1633
 
1589
 
        f = AtomicFile(ifn, 'wt')
 
1634
        f = AtomicFile(ifn, 'wb')
1590
1635
        try:
1591
1636
            f.write(igns.encode('utf-8'))
1592
1637
            f.commit()
1647
1692
    Root may be the top directory for tar, tgz and tbz2 formats. If none
1648
1693
    is given, the top directory will be the root name of the file.
1649
1694
 
 
1695
    If branch is omitted then the branch containing the CWD will be used.
 
1696
 
1650
1697
    Note: export of tree with non-ascii filenames to zip is not supported.
1651
1698
 
1652
1699
     Supported formats       Autodetected by extension
1657
1704
         tgz                      .tar.gz, .tgz
1658
1705
         zip                          .zip
1659
1706
    """
1660
 
    takes_args = ['dest']
 
1707
    takes_args = ['dest', 'branch?']
1661
1708
    takes_options = ['revision', 'format', 'root']
1662
 
    def run(self, dest, revision=None, format=None, root=None):
 
1709
    def run(self, dest, branch=None, revision=None, format=None, root=None):
1663
1710
        from bzrlib.export import export
1664
 
        tree = WorkingTree.open_containing(u'.')[0]
1665
 
        b = tree.branch
 
1711
 
 
1712
        if branch is None:
 
1713
            tree = WorkingTree.open_containing(u'.')[0]
 
1714
            b = tree.branch
 
1715
        else:
 
1716
            b = Branch.open(branch)
 
1717
            
1666
1718
        if revision is None:
1667
1719
            # should be tree.last_revision  FIXME
1668
1720
            rev_id = b.last_revision()
1669
1721
        else:
1670
1722
            if len(revision) != 1:
1671
 
                raise errors.BzrError('bzr export --revision takes exactly'
1672
 
                                      ' 1 argument')
 
1723
                raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1673
1724
            rev_id = revision[0].in_history(b).rev_id
1674
1725
        t = b.repository.revision_tree(rev_id)
1675
1726
        try:
1681
1732
class cmd_cat(Command):
1682
1733
    """Write a file's text from a previous revision."""
1683
1734
 
1684
 
    takes_options = ['revision']
 
1735
    takes_options = ['revision', 'name-from-revision']
1685
1736
    takes_args = ['filename']
1686
1737
 
1687
1738
    @display_command
1688
 
    def run(self, filename, revision=None):
 
1739
    def run(self, filename, revision=None, name_from_revision=False):
1689
1740
        if revision is not None and len(revision) != 1:
1690
 
            raise errors.BzrCommandError("bzr cat --revision takes exactly one number")
 
1741
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
 
1742
                                        " one number")
 
1743
 
1691
1744
        tree = None
1692
1745
        try:
1693
1746
            tree, relpath = WorkingTree.open_containing(filename)
1703
1756
            revision_id = b.last_revision()
1704
1757
        else:
1705
1758
            revision_id = revision[0].in_history(b).rev_id
1706
 
        b.print_file(relpath, revision_id)
 
1759
 
 
1760
        cur_file_id = tree.path2id(relpath)
 
1761
        rev_tree = b.repository.revision_tree(revision_id)
 
1762
        old_file_id = rev_tree.path2id(relpath)
 
1763
        
 
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))
 
1768
            else:
 
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)
 
1774
        else:
 
1775
            raise errors.BzrCommandError("%r is not present in revision %s" %
 
1776
                                         (filename, revision_id))
1707
1777
 
1708
1778
 
1709
1779
class cmd_local_time_offset(Command):
1763
1833
                StrictCommitFailed)
1764
1834
        from bzrlib.msgeditor import edit_commit_message, \
1765
1835
                make_commit_message_template
1766
 
        from tempfile import TemporaryFile
1767
1836
 
1768
1837
        # TODO: Need a blackbox test for invoking the external editor; may be
1769
1838
        # slightly problematic to run this cross-platform.
1770
1839
 
1771
1840
        # TODO: do more checks that the commit will succeed before 
1772
1841
        # 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
1842
        tree, selected_list = tree_files(selected_list)
1777
1843
        if selected_list == ['']:
1778
1844
            # workaround - commit of root of tree should be exactly the same
1782
1848
 
1783
1849
        if local and not tree.branch.get_bound_location():
1784
1850
            raise errors.LocalRequiresBoundBranch()
1785
 
        if message is None and not file:
1786
 
            template = make_commit_message_template(tree, selected_list)
1787
 
            message = edit_commit_message(template)
1788
 
            if message is None:
1789
 
                raise errors.BzrCommandError("please specify a commit message"
1790
 
                                             " with either --message or --file")
1791
 
        elif message and file:
1792
 
            raise errors.BzrCommandError("please specify either --message or --file")
1793
 
        
1794
 
        if file:
1795
 
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1796
1851
 
1797
 
        if message == "":
1798
 
            raise errors.BzrCommandError("empty commit message specified")
 
1852
        def get_message(commit_obj):
 
1853
            """Callback to get commit message"""
 
1854
            my_message = message
 
1855
            if my_message is None and not file:
 
1856
                template = make_commit_message_template(tree, selected_list)
 
1857
                my_message = edit_commit_message(template)
 
1858
                if my_message is None:
 
1859
                    raise errors.BzrCommandError("please specify a commit"
 
1860
                        " message with either --message or --file")
 
1861
            elif my_message and file:
 
1862
                raise errors.BzrCommandError(
 
1863
                    "please specify either --message or --file")
 
1864
            if file:
 
1865
                my_message = codecs.open(file, 'rt', 
 
1866
                                         bzrlib.user_encoding).read()
 
1867
            if my_message == "":
 
1868
                raise errors.BzrCommandError("empty commit message specified")
 
1869
            return my_message
1799
1870
        
1800
1871
        if verbose:
1801
1872
            reporter = ReportCommitToLog()
1802
1873
        else:
1803
1874
            reporter = NullCommitReporter()
1804
 
        
 
1875
 
1805
1876
        try:
1806
 
            tree.commit(message, specific_files=selected_list,
 
1877
            tree.commit(message_callback=get_message,
 
1878
                        specific_files=selected_list,
1807
1879
                        allow_pointless=unchanged, strict=strict, local=local,
1808
1880
                        reporter=reporter)
1809
1881
        except PointlessCommit:
1810
1882
            # FIXME: This should really happen before the file is read in;
1811
1883
            # perhaps prepare the commit; get the message; then actually commit
1812
1884
            raise errors.BzrCommandError("no changes to commit."
1813
 
                                         " use --unchanged to commit anyhow")
 
1885
                              " use --unchanged to commit anyhow")
1814
1886
        except ConflictsInTree:
1815
 
            raise errors.BzrCommandError("Conflicts detected in working tree.  "
1816
 
                'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
 
1887
            raise errors.BzrCommandError('Conflicts detected in working '
 
1888
                'tree.  Use "bzr conflicts" to list, "bzr resolve FILE" to'
 
1889
                ' resolve.')
1817
1890
        except StrictCommitFailed:
1818
 
            raise errors.BzrCommandError("Commit refused because there are unknown "
1819
 
                                         "files in the working tree.")
 
1891
            raise errors.BzrCommandError("Commit refused because there are"
 
1892
                              " unknown files in the working tree.")
1820
1893
        except errors.BoundBranchOutOfDate, e:
1821
1894
            raise errors.BzrCommandError(str(e) + "\n"
1822
 
                'To commit to master branch, run update and then commit.\n'
1823
 
                'You can also pass --local to commit to continue working '
1824
 
                'disconnected.')
 
1895
            'To commit to master branch, run update and then commit.\n'
 
1896
            'You can also pass --local to commit to continue working '
 
1897
            'disconnected.')
 
1898
 
1825
1899
 
1826
1900
class cmd_check(Command):
1827
1901
    """Validate consistency of branch history.
1842
1916
        check(branch, verbose)
1843
1917
 
1844
1918
 
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
1919
class cmd_upgrade(Command):
1865
1920
    """Upgrade branch storage to current format.
1866
1921
 
2018
2073
 
2019
2074
        if cache_dir is not None:
2020
2075
            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
2076
        print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2026
2077
        print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
2027
2078
        print
2028
 
        info('running tests...')
 
2079
        if testspecs_list is not None:
 
2080
            pattern = '|'.join(testspecs_list)
 
2081
        else:
 
2082
            pattern = ".*"
 
2083
        if benchmark:
 
2084
            test_suite_factory = benchmarks.test_suite
 
2085
            if verbose is None:
 
2086
                verbose = True
 
2087
            # TODO: should possibly lock the history file...
 
2088
            benchfile = open(".perf_history", "at")
 
2089
        else:
 
2090
            test_suite_factory = None
 
2091
            if verbose is None:
 
2092
                verbose = False
 
2093
            benchfile = None
2029
2094
        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)
 
2095
            result = selftest(verbose=verbose, 
 
2096
                              pattern=pattern,
 
2097
                              stop_on_failure=one, 
 
2098
                              keep_output=keep_output,
 
2099
                              transport=transport,
 
2100
                              test_suite_factory=test_suite_factory,
 
2101
                              lsprof_timed=lsprof_timed,
 
2102
                              bench_history=benchfile)
2063
2103
        finally:
2064
 
            ui.ui_factory = save_ui
 
2104
            if benchfile is not None:
 
2105
                benchfile.close()
 
2106
        if result:
 
2107
            info('tests passed')
 
2108
        else:
 
2109
            info('tests failed')
 
2110
        return int(not result)
2065
2111
 
2066
2112
 
2067
2113
class cmd_version(Command):
2361
2407
        else:
2362
2408
            return 0
2363
2409
 
 
2410
 
2364
2411
class cmd_revert(Command):
2365
2412
    """Revert files to a previous revision.
2366
2413
 
2412
2459
 
2413
2460
class cmd_assert_fail(Command):
2414
2461
    """Test reporting of assertion failures"""
 
2462
    # intended just for use in testing
 
2463
 
2415
2464
    hidden = True
 
2465
 
2416
2466
    def run(self):
2417
 
        assert False, "always fails"
 
2467
        raise AssertionError("always fails")
2418
2468
 
2419
2469
 
2420
2470
class cmd_help(Command):
2421
2471
    """Show help on a command or other topic.
2422
2472
 
2423
 
    For a list of all available commands, say 'bzr help commands'."""
 
2473
    For a list of all available commands, say 'bzr help commands'.
 
2474
    """
2424
2475
    takes_options = [Option('long', 'show help on all commands')]
2425
2476
    takes_args = ['topic?']
2426
2477
    aliases = ['?', '--help', '-?', '-h']
2427
2478
    
2428
2479
    @display_command
2429
2480
    def run(self, topic=None, long=False):
2430
 
        import help
 
2481
        import bzrlib.help
2431
2482
        if topic is None and long:
2432
2483
            topic = "commands"
2433
 
        help.help(topic)
 
2484
        bzrlib.help.help(topic)
2434
2485
 
2435
2486
 
2436
2487
class cmd_shell_complete(Command):
2437
2488
    """Show appropriate completions for context.
2438
2489
 
2439
 
    For a list of all available commands, say 'bzr shell-complete'."""
 
2490
    For a list of all available commands, say 'bzr shell-complete'.
 
2491
    """
2440
2492
    takes_args = ['context?']
2441
2493
    aliases = ['s-c']
2442
2494
    hidden = True
2450
2502
class cmd_fetch(Command):
2451
2503
    """Copy in history from another branch but don't merge it.
2452
2504
 
2453
 
    This is an internal method used for pull and merge."""
 
2505
    This is an internal method used for pull and merge.
 
2506
    """
2454
2507
    hidden = True
2455
2508
    takes_args = ['from_branch', 'to_branch']
2456
2509
    def run(self, from_branch, to_branch):
2463
2516
class cmd_missing(Command):
2464
2517
    """Show unmerged/unpulled revisions between two branches.
2465
2518
 
2466
 
    OTHER_BRANCH may be local or remote."""
 
2519
    OTHER_BRANCH may be local or remote.
 
2520
    """
2467
2521
    takes_args = ['other_branch?']
2468
2522
    takes_options = [Option('reverse', 'Reverse the order of revisions'),
2469
2523
                     Option('mine-only',