/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: Kent Gibson
  • Date: 2007-03-07 14:49:00 UTC
  • mfrom: (2324 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2350.
  • Revision ID: warthog618@gmail.com-20070307144900-6bt7twg47zul3w0w
merged bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
344
344
            file_ids_from=None):
345
345
        import bzrlib.add
346
346
 
 
347
        base_tree = None
347
348
        if file_ids_from is not None:
348
349
            try:
349
350
                base_tree, base_path = WorkingTree.open_containing(
359
360
            action = bzrlib.add.AddAction(to_file=self.outf,
360
361
                should_print=(not is_quiet()))
361
362
 
362
 
        added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
363
 
                                              action=action, save=not dry_run)
 
363
        if base_tree:
 
364
            base_tree.lock_read()
 
365
        try:
 
366
            added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
 
367
                action=action, save=not dry_run)
 
368
        finally:
 
369
            if base_tree is not None:
 
370
                base_tree.unlock()
364
371
        if len(ignored) > 0:
365
372
            if verbose:
366
373
                for glob in sorted(ignored.keys()):
432
439
            raise errors.BzrCommandError('invalid kind specified')
433
440
 
434
441
        work_tree, file_list = tree_files(file_list)
435
 
 
436
 
        if revision is not None:
437
 
            if len(revision) > 1:
438
 
                raise errors.BzrCommandError('bzr inventory --revision takes'
439
 
                                             ' exactly one revision identifier')
440
 
            revision_id = revision[0].in_history(work_tree.branch).rev_id
441
 
            tree = work_tree.branch.repository.revision_tree(revision_id)
442
 
                        
443
 
            # We include work_tree as well as 'tree' here
444
 
            # So that doing '-r 10 path/foo' will lookup whatever file
445
 
            # exists now at 'path/foo' even if it has been renamed, as
446
 
            # well as whatever files existed in revision 10 at path/foo
447
 
            trees = [tree, work_tree]
448
 
        else:
449
 
            tree = work_tree
450
 
            trees = [tree]
451
 
 
452
 
        if file_list is not None:
453
 
            file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
454
 
                                                      require_versioned=True)
455
 
            # find_ids_across_trees may include some paths that don't
456
 
            # exist in 'tree'.
457
 
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
458
 
                             for file_id in file_ids if file_id in tree)
459
 
        else:
460
 
            entries = tree.inventory.entries()
 
442
        work_tree.lock_read()
 
443
        try:
 
444
            if revision is not None:
 
445
                if len(revision) > 1:
 
446
                    raise errors.BzrCommandError(
 
447
                        'bzr inventory --revision takes exactly one revision'
 
448
                        ' identifier')
 
449
                revision_id = revision[0].in_history(work_tree.branch).rev_id
 
450
                tree = work_tree.branch.repository.revision_tree(revision_id)
 
451
 
 
452
                extra_trees = [work_tree]
 
453
                tree.lock_read()
 
454
            else:
 
455
                tree = work_tree
 
456
                extra_trees = []
 
457
 
 
458
            if file_list is not None:
 
459
                file_ids = tree.paths2ids(file_list, trees=extra_trees,
 
460
                                          require_versioned=True)
 
461
                # find_ids_across_trees may include some paths that don't
 
462
                # exist in 'tree'.
 
463
                entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
 
464
                                 for file_id in file_ids if file_id in tree)
 
465
            else:
 
466
                entries = tree.inventory.entries()
 
467
        finally:
 
468
            tree.unlock()
 
469
            if tree is not work_tree:
 
470
                work_tree.unlock()
461
471
 
462
472
        for path, entry in entries:
463
473
            if kind and kind != entry.kind:
601
611
        old_rh = branch_to.revision_history()
602
612
        if tree_to is not None:
603
613
            result = tree_to.pull(branch_from, overwrite, rev_id,
604
 
                delta.ChangeReporter(tree_to.inventory))
 
614
                delta.ChangeReporter(unversioned_filter=tree_to.is_ignored))
605
615
        else:
606
616
            result = branch_to.pull(branch_from, overwrite, rev_id)
607
617
 
972
982
    @display_command
973
983
    def run(self, dir=u'.'):
974
984
        tree = WorkingTree.open_containing(dir)[0]
975
 
        old_inv = tree.basis_tree().inventory
976
 
        new_inv = tree.read_working_inventory()
977
 
        renames = list(_mod_tree.find_renames(old_inv, new_inv))
978
 
        renames.sort()
979
 
        for old_name, new_name in renames:
980
 
            self.outf.write("%s => %s\n" % (old_name, new_name))
 
985
        tree.lock_read()
 
986
        try:
 
987
            new_inv = tree.inventory
 
988
            old_tree = tree.basis_tree()
 
989
            old_tree.lock_read()
 
990
            try:
 
991
                old_inv = old_tree.inventory
 
992
                renames = list(_mod_tree.find_renames(old_inv, new_inv))
 
993
                renames.sort()
 
994
                for old_name, new_name in renames:
 
995
                    self.outf.write("%s => %s\n" % (old_name, new_name))
 
996
            finally:
 
997
                old_tree.unlock()
 
998
        finally:
 
999
            tree.unlock()
981
1000
 
982
1001
 
983
1002
class cmd_update(Command):
1088
1107
    @display_command
1089
1108
    def run(self, filename):
1090
1109
        tree, relpath = WorkingTree.open_containing(filename)
1091
 
        i = tree.inventory.path2id(relpath)
 
1110
        i = tree.path2id(relpath)
1092
1111
        if i is None:
1093
1112
            raise errors.NotVersionedError(filename)
1094
1113
        else:
1108
1127
    @display_command
1109
1128
    def run(self, filename):
1110
1129
        tree, relpath = WorkingTree.open_containing(filename)
1111
 
        inv = tree.inventory
1112
 
        fid = inv.path2id(relpath)
 
1130
        fid = tree.path2id(relpath)
1113
1131
        if fid is None:
1114
1132
            raise errors.NotVersionedError(filename)
1115
 
        for fip in inv.get_idpath(fid):
1116
 
            self.outf.write(fip + '\n')
 
1133
        segments = osutils.splitpath(relpath)
 
1134
        for pos in range(1, len(segments) + 1):
 
1135
            path = osutils.joinpath(segments[:pos])
 
1136
            self.outf.write("%s\n" % tree.path2id(path))
1117
1137
 
1118
1138
 
1119
1139
class cmd_reconcile(Command):
1424
1444
    @display_command
1425
1445
    def run(self, show_ids=False):
1426
1446
        tree = WorkingTree.open_containing(u'.')[0]
1427
 
        old = tree.basis_tree()
1428
 
        for path, ie in old.inventory.iter_entries():
1429
 
            if not tree.has_id(ie.file_id):
1430
 
                self.outf.write(path)
1431
 
                if show_ids:
1432
 
                    self.outf.write(' ')
1433
 
                    self.outf.write(ie.file_id)
1434
 
                self.outf.write('\n')
 
1447
        tree.lock_read()
 
1448
        try:
 
1449
            old = tree.basis_tree()
 
1450
            old.lock_read()
 
1451
            try:
 
1452
                for path, ie in old.inventory.iter_entries():
 
1453
                    if not tree.has_id(ie.file_id):
 
1454
                        self.outf.write(path)
 
1455
                        if show_ids:
 
1456
                            self.outf.write(' ')
 
1457
                            self.outf.write(ie.file_id)
 
1458
                        self.outf.write('\n')
 
1459
            finally:
 
1460
                old.unlock()
 
1461
        finally:
 
1462
            tree.unlock()
1435
1463
 
1436
1464
 
1437
1465
class cmd_modified(Command):
1461
1489
    @display_command
1462
1490
    def run(self):
1463
1491
        wt = WorkingTree.open_containing(u'.')[0]
1464
 
        basis_inv = wt.basis_tree().inventory
1465
 
        inv = wt.inventory
1466
 
        for file_id in inv:
1467
 
            if file_id in basis_inv:
1468
 
                continue
1469
 
            if inv.is_root(file_id) and len(basis_inv) == 0:
1470
 
                continue
1471
 
            path = inv.id2path(file_id)
1472
 
            if not os.access(osutils.abspath(path), os.F_OK):
1473
 
                continue
1474
 
            self.outf.write(path + '\n')
 
1492
        wt.lock_read()
 
1493
        try:
 
1494
            basis = wt.basis_tree()
 
1495
            basis.lock_read()
 
1496
            try:
 
1497
                basis_inv = basis.inventory
 
1498
                inv = wt.inventory
 
1499
                for file_id in inv:
 
1500
                    if file_id in basis_inv:
 
1501
                        continue
 
1502
                    if inv.is_root(file_id) and len(basis_inv) == 0:
 
1503
                        continue
 
1504
                    path = inv.id2path(file_id)
 
1505
                    if not os.access(osutils.abspath(path), os.F_OK):
 
1506
                        continue
 
1507
                    self.outf.write(path + '\n')
 
1508
            finally:
 
1509
                basis.unlock()
 
1510
        finally:
 
1511
            wt.unlock()
1475
1512
 
1476
1513
 
1477
1514
class cmd_root(Command):
1543
1580
            if fp != '':
1544
1581
                if tree is None:
1545
1582
                    tree = b.basis_tree()
1546
 
                inv = tree.inventory
1547
 
                file_id = inv.path2id(fp)
 
1583
                file_id = tree.path2id(fp)
1548
1584
                if file_id is None:
1549
1585
                    raise errors.BzrCommandError(
1550
1586
                        "Path does not have any revision history: %s" %
1638
1674
    def run(self, filename):
1639
1675
        tree, relpath = WorkingTree.open_containing(filename)
1640
1676
        b = tree.branch
1641
 
        inv = tree.read_working_inventory()
1642
 
        file_id = inv.path2id(relpath)
 
1677
        file_id = tree.path2id(relpath)
1643
1678
        for revno, revision_id, what in log.find_touching_revisions(b, file_id):
1644
1679
            self.outf.write("%6d %s\n" % (revno, what))
1645
1680
 
1698
1733
        elif tree is None:
1699
1734
            tree = branch.basis_tree()
1700
1735
 
1701
 
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1702
 
            if fp.startswith(relpath):
1703
 
                fp = osutils.pathjoin(prefix, fp[len(relpath):])
1704
 
                if non_recursive and '/' in fp:
1705
 
                    continue
1706
 
                if not all and not selection[fc]:
1707
 
                    continue
1708
 
                if kind is not None and fkind != kind:
1709
 
                    continue
1710
 
                if verbose:
1711
 
                    kindch = entry.kind_character()
1712
 
                    outstring = '%-8s %s%s' % (fc, fp, kindch)
1713
 
                    if show_ids and fid is not None:
1714
 
                        outstring = "%-50s %s" % (outstring, fid)
1715
 
                    self.outf.write(outstring + '\n')
1716
 
                elif null:
1717
 
                    self.outf.write(fp + '\0')
1718
 
                    if show_ids:
 
1736
        tree.lock_read()
 
1737
        try:
 
1738
            for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
 
1739
                if fp.startswith(relpath):
 
1740
                    fp = osutils.pathjoin(prefix, fp[len(relpath):])
 
1741
                    if non_recursive and '/' in fp:
 
1742
                        continue
 
1743
                    if not all and not selection[fc]:
 
1744
                        continue
 
1745
                    if kind is not None and fkind != kind:
 
1746
                        continue
 
1747
                    if verbose:
 
1748
                        kindch = entry.kind_character()
 
1749
                        outstring = '%-8s %s%s' % (fc, fp, kindch)
 
1750
                        if show_ids and fid is not None:
 
1751
                            outstring = "%-50s %s" % (outstring, fid)
 
1752
                        self.outf.write(outstring + '\n')
 
1753
                    elif null:
 
1754
                        self.outf.write(fp + '\0')
 
1755
                        if show_ids:
 
1756
                            if fid is not None:
 
1757
                                self.outf.write(fid)
 
1758
                            self.outf.write('\0')
 
1759
                        self.outf.flush()
 
1760
                    else:
1719
1761
                        if fid is not None:
1720
 
                            self.outf.write(fid)
1721
 
                        self.outf.write('\0')
1722
 
                    self.outf.flush()
1723
 
                else:
1724
 
                    if fid is not None:
1725
 
                        my_id = fid
1726
 
                    else:
1727
 
                        my_id = ''
1728
 
                    if show_ids:
1729
 
                        self.outf.write('%-50s %s\n' % (fp, my_id))
1730
 
                    else:
1731
 
                        self.outf.write(fp + '\n')
 
1762
                            my_id = fid
 
1763
                        else:
 
1764
                            my_id = ''
 
1765
                        if show_ids:
 
1766
                            self.outf.write('%-50s %s\n' % (fp, my_id))
 
1767
                        else:
 
1768
                            self.outf.write(fp + '\n')
 
1769
        finally:
 
1770
            tree.unlock()
1732
1771
 
1733
1772
 
1734
1773
class cmd_unknowns(Command):
1827
1866
        finally:
1828
1867
            f.close()
1829
1868
 
1830
 
        inv = tree.inventory
1831
 
        if inv.path2id('.bzrignore'):
1832
 
            mutter('.bzrignore is already versioned')
1833
 
        else:
1834
 
            mutter('need to make new .bzrignore file versioned')
 
1869
        if not tree.path2id('.bzrignore'):
1835
1870
            tree.add(['.bzrignore'])
1836
1871
 
1837
1872
 
1842
1877
    @display_command
1843
1878
    def run(self):
1844
1879
        tree = WorkingTree.open_containing(u'.')[0]
1845
 
        for path, file_class, kind, file_id, entry in tree.list_files():
1846
 
            if file_class != 'I':
1847
 
                continue
1848
 
            ## XXX: Slightly inefficient since this was already calculated
1849
 
            pat = tree.is_ignored(path)
1850
 
            print '%-50s %s' % (path, pat)
 
1880
        tree.lock_read()
 
1881
        try:
 
1882
            for path, file_class, kind, file_id, entry in tree.list_files():
 
1883
                if file_class != 'I':
 
1884
                    continue
 
1885
                ## XXX: Slightly inefficient since this was already calculated
 
1886
                pat = tree.is_ignored(path)
 
1887
                print '%-50s %s' % (path, pat)
 
1888
        finally:
 
1889
            tree.unlock()
1851
1890
 
1852
1891
 
1853
1892
class cmd_lookup_revision(Command):
2124
2163
                        value_switches=True, title='Branch format'),
2125
2164
                    ]
2126
2165
 
2127
 
 
2128
2166
    def run(self, url='.', format=None):
2129
2167
        from bzrlib.upgrade import upgrade
2130
2168
        if format is None:
2222
2260
            run only tests relating to 'ignore'
2223
2261
        bzr --no-plugins selftest -v
2224
2262
            disable plugins and list tests as they're run
 
2263
 
 
2264
    For each test, that needs actual disk access, bzr create their own
 
2265
    subdirectory in the temporary testing directory (testXXXX.tmp).
 
2266
    By default the name of such subdirectory is based on the name of the test.
 
2267
    If option '--numbered-dirs' is given, bzr will use sequent numbers
 
2268
    of running tests to create such subdirectories. This is default behavior
 
2269
    on Windows because of path length limitation.
2225
2270
    """
2226
2271
    # TODO: --list should give a list of all available tests
2227
2272
 
2264
2309
                                 ' without running tests'),
2265
2310
                     Option('first',
2266
2311
                            help='run all tests, but run specified tests first',
2267
 
                            )
 
2312
                            ),
 
2313
                     Option('numbered-dirs',
 
2314
                            help='use numbered dirs for TestCaseInTempDir'),
2268
2315
                     ]
2269
2316
    encoding_type = 'replace'
2270
2317
 
2271
2318
    def run(self, testspecs_list=None, verbose=None, one=False,
2272
2319
            keep_output=False, transport=None, benchmark=None,
2273
2320
            lsprof_timed=None, cache_dir=None, clean_output=False,
2274
 
            first=False):
 
2321
            first=False, numbered_dirs=None):
2275
2322
        import bzrlib.ui
2276
2323
        from bzrlib.tests import selftest
2277
2324
        import bzrlib.benchmarks as benchmarks
2282
2329
            clean_selftest_output()
2283
2330
            return 0
2284
2331
 
 
2332
        if numbered_dirs is None and sys.platform == 'win32':
 
2333
            numbered_dirs = True
 
2334
 
2285
2335
        if cache_dir is not None:
2286
2336
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2287
2337
        print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2312
2362
                              lsprof_timed=lsprof_timed,
2313
2363
                              bench_history=benchfile,
2314
2364
                              matching_tests_first=first,
 
2365
                              numbered_dirs=numbered_dirs,
2315
2366
                              )
2316
2367
        finally:
2317
2368
            if benchfile is not None:
2440
2491
            merge_type = _mod_merge.Merge3Merger
2441
2492
 
2442
2493
        if directory is None: directory = u'.'
 
2494
        # XXX: jam 20070225 WorkingTree should be locked before you extract its
 
2495
        #      inventory. Because merge is a mutating operation, it really
 
2496
        #      should be a lock_write() for the whole cmd_merge operation.
 
2497
        #      However, cmd_merge open's its own tree in _merge_helper, which
 
2498
        #      means if we lock here, the later lock_write() will always block.
 
2499
        #      Either the merge helper code should be updated to take a tree,
 
2500
        #      (What about tree.merge_from_branch?)
2443
2501
        tree = WorkingTree.open_containing(directory)[0]
2444
 
        change_reporter = delta.ChangeReporter(tree.inventory)
 
2502
        change_reporter = delta.ChangeReporter(
 
2503
            unversioned_filter=tree.is_ignored)
2445
2504
 
2446
2505
        if branch is not None:
2447
2506
            try:
2911
2970
                raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2912
2971
            else:
2913
2972
                revision_id = revision[0].in_history(branch).rev_id
2914
 
            file_id = tree.inventory.path2id(relpath)
 
2973
            file_id = tree.path2id(relpath)
2915
2974
            tree = branch.repository.revision_tree(revision_id)
2916
2975
            file_version = tree.inventory[file_id].revision
2917
2976
            annotate_file(branch, file_version, file_id, long, all, sys.stdout,
3179
3238
            sys.stdout.flush()
3180
3239
        server.serve()
3181
3240
 
 
3241
class cmd_join(Command):
 
3242
    """Combine a subtree into its containing tree.
 
3243
    
 
3244
    This is marked as a merge of the subtree into the containing tree, and all
 
3245
    history is preserved.
 
3246
    """
 
3247
 
 
3248
    takes_args = ['tree']
 
3249
    takes_options = [Option('reference', 'join by reference')]
 
3250
 
 
3251
    def run(self, tree, reference=False):
 
3252
        sub_tree = WorkingTree.open(tree)
 
3253
        parent_dir = osutils.dirname(sub_tree.basedir)
 
3254
        containing_tree = WorkingTree.open_containing(parent_dir)[0]
 
3255
        repo = containing_tree.branch.repository
 
3256
        if not repo.supports_rich_root():
 
3257
            raise errors.BzrCommandError(
 
3258
                "Can't join trees because %s doesn't support rich root data.\n"
 
3259
                "You can use bzr upgrade on the repository."
 
3260
                % (repo,))
 
3261
        if reference:
 
3262
            try:
 
3263
                containing_tree.add_reference(sub_tree)
 
3264
            except errors.BadReferenceTarget, e:
 
3265
                # XXX: Would be better to just raise a nicely printable
 
3266
                # exception from the real origin.  Also below.  mbp 20070306
 
3267
                raise errors.BzrCommandError("Cannot join %s.  %s" %
 
3268
                                             (tree, e.reason))
 
3269
        else:
 
3270
            try:
 
3271
                containing_tree.subsume(sub_tree)
 
3272
            except errors.BadSubsumeSource, e:
 
3273
                raise errors.BzrCommandError("Cannot join %s.  %s" % 
 
3274
                                             (tree, e.reason))
 
3275
 
 
3276
 
 
3277
class cmd_split(Command):
 
3278
    """Split a tree into two trees.
 
3279
    """
 
3280
 
 
3281
    takes_args = ['tree']
 
3282
 
 
3283
    def run(self, tree):
 
3284
        containing_tree, subdir = WorkingTree.open_containing(tree)
 
3285
        sub_id = containing_tree.path2id(subdir)
 
3286
        if sub_id is None:
 
3287
            raise errors.NotVersionedError(subdir)
 
3288
        try:
 
3289
            containing_tree.extract(sub_id)
 
3290
        except errors.RootNotRich:
 
3291
            raise errors.UpgradeRequired(containing_tree.branch.base)
 
3292
 
 
3293
 
3182
3294
 
3183
3295
class cmd_tag(Command):
3184
3296
    """Create a tag naming a revision.
3312
3424
                                     " type %s." % merge_type)
3313
3425
    if reprocess and show_base:
3314
3426
        raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
 
3427
    # TODO: jam 20070226 We should really lock these trees earlier. However, we
 
3428
    #       only want to take out a lock_tree_write() if we don't have to pull
 
3429
    #       any ancestry. But merge might fetch ancestry in the middle, in
 
3430
    #       which case we would need a lock_write().
 
3431
    #       Because we cannot upgrade locks, for now we live with the fact that
 
3432
    #       the tree will be locked multiple times during a merge. (Maybe
 
3433
    #       read-only some of the time, but it means things will get read
 
3434
    #       multiple times.)
3315
3435
    try:
3316
3436
        merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3317
3437
                                   pb=pb, change_reporter=change_reporter)