~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Robert Collins
  • Date: 2010-05-06 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
528
528
        if tree:
529
529
            try:
530
530
                wt = WorkingTree.open_containing(location)[0]
531
 
                wt.lock_read()
 
531
                self.add_cleanup(wt.lock_read().unlock)
532
532
            except (errors.NoWorkingTree, errors.NotLocalUrl):
533
533
                raise errors.NoWorkingTree(location)
534
 
            self.add_cleanup(wt.unlock)
535
534
            revid = wt.last_revision()
536
535
            try:
537
536
                revno_t = wt.branch.revision_id_to_dotted_revno(revid)
540
539
            revno = ".".join(str(n) for n in revno_t)
541
540
        else:
542
541
            b = Branch.open_containing(location)[0]
543
 
            b.lock_read()
544
 
            self.add_cleanup(b.unlock)
 
542
            self.add_cleanup(b.lock_read().unlock)
545
543
            revno = b.revno()
546
544
        self.cleanup_now()
547
545
        self.outf.write(str(revno) + '\n')
570
568
        try:
571
569
            wt = WorkingTree.open_containing(directory)[0]
572
570
            b = wt.branch
573
 
            wt.lock_read()
574
 
            self.add_cleanup(wt.unlock)
 
571
            self.add_cleanup(wt.lock_read().unlock)
575
572
        except (errors.NoWorkingTree, errors.NotLocalUrl):
576
573
            wt = None
577
574
            b = Branch.open_containing(directory)[0]
578
 
            b.lock_read()
579
 
            self.add_cleanup(b.unlock)
 
575
            self.add_cleanup(b.lock_read().unlock)
580
576
        revision_ids = []
581
577
        if revision is not None:
582
578
            revision_ids.extend(rev.as_revision_id(b) for rev in revision)
681
677
                should_print=(not is_quiet()))
682
678
 
683
679
        if base_tree:
684
 
            base_tree.lock_read()
685
 
            self.add_cleanup(base_tree.unlock)
 
680
            self.add_cleanup(base_tree.lock_read().unlock)
686
681
        tree, file_list = tree_files_for_add(file_list)
687
682
        added, ignored = tree.smart_add(file_list, not
688
683
            no_recurse, action=action, save=not dry_run)
760
755
 
761
756
        revision = _get_one_revision('inventory', revision)
762
757
        work_tree, file_list = tree_files(file_list)
763
 
        work_tree.lock_read()
764
 
        self.add_cleanup(work_tree.unlock)
 
758
        self.add_cleanup(work_tree.lock_read().unlock)
765
759
        if revision is not None:
766
760
            tree = revision.as_tree(work_tree.branch)
767
761
 
768
762
            extra_trees = [work_tree]
769
 
            tree.lock_read()
770
 
            self.add_cleanup(tree.unlock)
 
763
            self.add_cleanup(tree.lock_read().unlock)
771
764
        else:
772
765
            tree = work_tree
773
766
            extra_trees = []
833
826
        if len(names_list) < 2:
834
827
            raise errors.BzrCommandError("missing file argument")
835
828
        tree, rel_names = tree_files(names_list, canonicalize=False)
836
 
        tree.lock_tree_write()
837
 
        self.add_cleanup(tree.unlock)
 
829
        self.add_cleanup(tree.lock_tree_write().unlock)
838
830
        self._run(tree, names_list, rel_names, after)
839
831
 
840
832
    def run_auto(self, names_list, after, dry_run):
845
837
            raise errors.BzrCommandError('--after cannot be specified with'
846
838
                                         ' --auto.')
847
839
        work_tree, file_list = tree_files(names_list, default_branch='.')
848
 
        work_tree.lock_tree_write()
849
 
        self.add_cleanup(work_tree.unlock)
 
840
        self.add_cleanup(work_tree.lock_tree_write().unlock)
850
841
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
851
842
 
852
843
    def _run(self, tree, names_list, rel_names, after):
986
977
        try:
987
978
            tree_to = WorkingTree.open_containing(directory)[0]
988
979
            branch_to = tree_to.branch
989
 
            tree_to.lock_write()
990
 
            self.add_cleanup(tree_to.unlock)
 
980
            self.add_cleanup(tree_to.lock_write().unlock)
991
981
        except errors.NoWorkingTree:
992
982
            tree_to = None
993
983
            branch_to = Branch.open_containing(directory)[0]
994
 
            branch_to.lock_write()
995
 
            self.add_cleanup(branch_to.unlock)
 
984
            self.add_cleanup(branch_to.lock_write().unlock)
996
985
 
997
986
        if local and not branch_to.get_bound_location():
998
987
            raise errors.LocalRequiresBoundBranch()
1029
1018
        else:
1030
1019
            branch_from = Branch.open(location,
1031
1020
                possible_transports=possible_transports)
1032
 
            branch_from.lock_read()
1033
 
            self.add_cleanup(branch_from.unlock)
 
1021
            self.add_cleanup(branch_from.lock_read().unlock)
1034
1022
 
1035
1023
            if branch_to.get_parent() is None or remember:
1036
1024
                branch_to.set_parent(branch_from.base)
1219
1207
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1220
1208
            from_location)
1221
1209
        revision = _get_one_revision('branch', revision)
1222
 
        br_from.lock_read()
1223
 
        self.add_cleanup(br_from.unlock)
 
1210
        self.add_cleanup(br_from.lock_read().unlock)
1224
1211
        if revision is not None:
1225
1212
            revision_id = revision.as_revision_id(br_from)
1226
1213
        else:
1366
1353
    @display_command
1367
1354
    def run(self, dir=u'.'):
1368
1355
        tree = WorkingTree.open_containing(dir)[0]
1369
 
        tree.lock_read()
1370
 
        self.add_cleanup(tree.unlock)
 
1356
        self.add_cleanup(tree.lock_read().unlock)
1371
1357
        new_inv = tree.inventory
1372
1358
        old_tree = tree.basis_tree()
1373
 
        old_tree.lock_read()
1374
 
        self.add_cleanup(old_tree.unlock)
 
1359
        self.add_cleanup(old_tree.lock_read().unlock)
1375
1360
        old_inv = old_tree.inventory
1376
1361
        renames = []
1377
1362
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1415
1400
        master = branch.get_master_branch(
1416
1401
            possible_transports=possible_transports)
1417
1402
        if master is not None:
1418
 
            tree.lock_write()
1419
1403
            branch_location = master.base
 
1404
            tree.lock_write()
1420
1405
        else:
 
1406
            branch_location = tree.branch.base
1421
1407
            tree.lock_tree_write()
1422
 
            branch_location = tree.branch.base
1423
1408
        self.add_cleanup(tree.unlock)
1424
1409
        # get rid of the final '/' and be ready for display
1425
1410
        branch_location = urlutils.unescape_for_display(
1545
1530
        if file_list is not None:
1546
1531
            file_list = [f for f in file_list]
1547
1532
 
1548
 
        tree.lock_write()
1549
 
        self.add_cleanup(tree.unlock)
 
1533
        self.add_cleanup(tree.lock_write().unlock)
1550
1534
        # Heuristics should probably all move into tree.remove_smart or
1551
1535
        # some such?
1552
1536
        if new:
2008
1992
    @display_command
2009
1993
    def run(self, show_ids=False):
2010
1994
        tree = WorkingTree.open_containing(u'.')[0]
2011
 
        tree.lock_read()
2012
 
        self.add_cleanup(tree.unlock)
 
1995
        self.add_cleanup(tree.lock_read().unlock)
2013
1996
        old = tree.basis_tree()
2014
 
        old.lock_read()
2015
 
        self.add_cleanup(old.unlock)
 
1997
        self.add_cleanup(old.lock_read().unlock)
2016
1998
        for path, ie in old.inventory.iter_entries():
2017
1999
            if not tree.has_id(ie.file_id):
2018
2000
                self.outf.write(path)
2060
2042
    @display_command
2061
2043
    def run(self, null=False):
2062
2044
        wt = WorkingTree.open_containing(u'.')[0]
2063
 
        wt.lock_read()
2064
 
        self.add_cleanup(wt.unlock)
 
2045
        self.add_cleanup(wt.lock_read().unlock)
2065
2046
        basis = wt.basis_tree()
2066
 
        basis.lock_read()
2067
 
        self.add_cleanup(basis.unlock)
 
2047
        self.add_cleanup(basis.lock_read().unlock)
2068
2048
        basis_inv = basis.inventory
2069
2049
        inv = wt.inventory
2070
2050
        for file_id in inv:
2352
2332
        if file_list:
2353
2333
            # find the file ids to log and check for directory filtering
2354
2334
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2355
 
                revision, file_list)
2356
 
            self.add_cleanup(b.unlock)
 
2335
                revision, file_list, self.add_cleanup)
2357
2336
            for relpath, file_id, kind in file_info_list:
2358
2337
                if file_id is None:
2359
2338
                    raise errors.BzrCommandError(
2377
2356
                location = '.'
2378
2357
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2379
2358
            b = dir.open_branch()
2380
 
            b.lock_read()
2381
 
            self.add_cleanup(b.unlock)
 
2359
            self.add_cleanup(b.lock_read().unlock)
2382
2360
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2383
2361
 
2384
2362
        # Decide on the type of delta & diff filtering to use
2508
2486
        tree, relpath = WorkingTree.open_containing(filename)
2509
2487
        file_id = tree.path2id(relpath)
2510
2488
        b = tree.branch
2511
 
        b.lock_read()
2512
 
        self.add_cleanup(b.unlock)
 
2489
        self.add_cleanup(b.lock_read().unlock)
2513
2490
        touching_revs = log.find_touching_revisions(b, file_id)
2514
2491
        for revno, revision_id, what in touching_revs:
2515
2492
            self.outf.write("%6d %s\n" % (revno, what))
2584
2561
                view_str = views.view_display_str(view_files)
2585
2562
                note("Ignoring files outside view. View is %s" % view_str)
2586
2563
 
2587
 
        tree.lock_read()
2588
 
        self.add_cleanup(tree.unlock)
 
2564
        self.add_cleanup(tree.lock_read().unlock)
2589
2565
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2590
2566
            from_dir=relpath, recursive=recursive):
2591
2567
            # Apply additional masking
2770
2746
    @display_command
2771
2747
    def run(self):
2772
2748
        tree = WorkingTree.open_containing(u'.')[0]
2773
 
        tree.lock_read()
2774
 
        self.add_cleanup(tree.unlock)
 
2749
        self.add_cleanup(tree.lock_read().unlock)
2775
2750
        for path, file_class, kind, file_id, entry in tree.list_files():
2776
2751
            if file_class != 'I':
2777
2752
                continue
2890
2865
                                         " one revision specifier")
2891
2866
        tree, branch, relpath = \
2892
2867
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2893
 
        branch.lock_read()
2894
 
        self.add_cleanup(branch.unlock)
 
2868
        self.add_cleanup(branch.lock_read().unlock)
2895
2869
        return self._run(tree, branch, relpath, filename, revision,
2896
2870
                         name_from_revision, filters)
2897
2871
 
2900
2874
        if tree is None:
2901
2875
            tree = b.basis_tree()
2902
2876
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2903
 
        rev_tree.lock_read()
2904
 
        self.add_cleanup(rev_tree.unlock)
 
2877
        self.add_cleanup(rev_tree.lock_read().unlock)
2905
2878
 
2906
2879
        old_file_id = rev_tree.path2id(relpath)
2907
2880
 
3690
3663
 
3691
3664
        branch1 = Branch.open_containing(branch)[0]
3692
3665
        branch2 = Branch.open_containing(other)[0]
3693
 
        branch1.lock_read()
3694
 
        self.add_cleanup(branch1.unlock)
3695
 
        branch2.lock_read()
3696
 
        self.add_cleanup(branch2.unlock)
 
3666
        self.add_cleanup(branch1.lock_read().unlock)
 
3667
        self.add_cleanup(branch2.lock_read().unlock)
3697
3668
        last1 = ensure_null(branch1.last_revision())
3698
3669
        last2 = ensure_null(branch2.last_revision())
3699
3670
 
3837
3808
            unversioned_filter=tree.is_ignored, view_info=view_info)
3838
3809
        pb = ui.ui_factory.nested_progress_bar()
3839
3810
        self.add_cleanup(pb.finished)
3840
 
        tree.lock_write()
3841
 
        self.add_cleanup(tree.unlock)
 
3811
        self.add_cleanup(tree.lock_write().unlock)
3842
3812
        if location is not None:
3843
3813
            try:
3844
3814
                mergeable = bundle.read_mergeable_from_url(location,
4100
4070
        if merge_type is None:
4101
4071
            merge_type = _mod_merge.Merge3Merger
4102
4072
        tree, file_list = tree_files(file_list)
4103
 
        tree.lock_write()
4104
 
        self.add_cleanup(tree.unlock)
 
4073
        self.add_cleanup(tree.lock_write().unlock)
4105
4074
        parents = tree.get_parent_ids()
4106
4075
        if len(parents) != 2:
4107
4076
            raise errors.BzrCommandError("Sorry, remerge only works after normal"
4217
4186
    def run(self, revision=None, no_backup=False, file_list=None,
4218
4187
            forget_merges=None):
4219
4188
        tree, file_list = tree_files(file_list)
4220
 
        tree.lock_tree_write()
4221
 
        self.add_cleanup(tree.unlock)
 
4189
        self.add_cleanup(tree.lock_tree_write().unlock)
4222
4190
        if forget_merges:
4223
4191
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4224
4192
        else:
4360
4328
            restrict = 'remote'
4361
4329
 
4362
4330
        local_branch = Branch.open_containing(u".")[0]
4363
 
        local_branch.lock_read()
4364
 
        self.add_cleanup(local_branch.unlock)
 
4331
        self.add_cleanup(local_branch.lock_read().unlock)
4365
4332
 
4366
4333
        parent = local_branch.get_parent()
4367
4334
        if other_branch is None:
4378
4345
        if remote_branch.base == local_branch.base:
4379
4346
            remote_branch = local_branch
4380
4347
        else:
4381
 
            remote_branch.lock_read()
4382
 
            self.add_cleanup(remote_branch.unlock)
 
4348
            self.add_cleanup(remote_branch.lock_read().unlock)
4383
4349
 
4384
4350
        local_revid_range = _revision_range_to_revid_range(
4385
4351
            _get_revision_range(my_revision, local_branch,
4440
4406
            message("Branches are up to date.\n")
4441
4407
        self.cleanup_now()
4442
4408
        if not status_code and parent is None and other_branch is not None:
4443
 
            local_branch.lock_write()
4444
 
            self.add_cleanup(local_branch.unlock)
 
4409
            self.add_cleanup(local_branch.lock_write().unlock)
4445
4410
            # handle race conditions - a parent might be set while we run.
4446
4411
            if local_branch.get_parent() is None:
4447
4412
                local_branch.set_parent(remote_branch.base)
4547
4512
            b = Branch.open_containing(branch)[0]
4548
4513
        else:
4549
4514
            b = Branch.open(branch)
4550
 
        b.lock_read()
4551
 
        self.add_cleanup(b.unlock)
 
4515
        self.add_cleanup(b.lock_read().unlock)
4552
4516
        if revision is None:
4553
4517
            rev_id = b.last_revision()
4554
4518
        else:
4588
4552
        wt, branch, relpath = \
4589
4553
            bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4590
4554
        if wt is not None:
4591
 
            wt.lock_read()
4592
 
            self.add_cleanup(wt.unlock)
 
4555
            self.add_cleanup(wt.lock_read().unlock)
4593
4556
        else:
4594
 
            branch.lock_read()
4595
 
            self.add_cleanup(branch.unlock)
 
4557
            self.add_cleanup(branch.lock_read().unlock)
4596
4558
        tree = _get_one_revision_tree('annotate', revision, branch=branch)
4597
 
        tree.lock_read()
4598
 
        self.add_cleanup(tree.unlock)
 
4559
        self.add_cleanup(tree.lock_read().unlock)
4599
4560
        if wt is not None:
4600
4561
            file_id = wt.path2id(relpath)
4601
4562
        else:
4627
4588
        if revision_id_list is None and revision is None:
4628
4589
            raise errors.BzrCommandError('You must supply either --revision or a revision_id')
4629
4590
        b = WorkingTree.open_containing(u'.')[0].branch
4630
 
        b.lock_write()
4631
 
        self.add_cleanup(b.unlock)
 
4591
        self.add_cleanup(b.lock_write().unlock)
4632
4592
        return self._run(b, revision_id_list, revision)
4633
4593
 
4634
4594
    def _run(self, b, revision_id_list, revision):
4784
4744
            b = control.open_branch()
4785
4745
 
4786
4746
        if tree is not None:
4787
 
            tree.lock_write()
4788
 
            self.add_cleanup(tree.unlock)
 
4747
            self.add_cleanup(tree.lock_write().unlock)
4789
4748
        else:
4790
 
            b.lock_write()
4791
 
            self.add_cleanup(b.unlock)
 
4749
            self.add_cleanup(b.lock_write().unlock)
4792
4750
        return self._run(b, tree, dry_run, verbose, revision, force, local=local)
4793
4751
 
4794
4752
    def _run(self, b, tree, dry_run, verbose, revision, force, local=False):
5357
5315
            revision=None,
5358
5316
            ):
5359
5317
        branch, relpath = Branch.open_containing(directory)
5360
 
        branch.lock_write()
5361
 
        self.add_cleanup(branch.unlock)
 
5318
        self.add_cleanup(branch.lock_write().unlock)
5362
5319
        if delete:
5363
5320
            if tag_name is None:
5364
5321
                raise errors.BzrCommandError("No tag specified to delete.")
5419
5376
        if not tags:
5420
5377
            return
5421
5378
 
5422
 
        branch.lock_read()
5423
 
        self.add_cleanup(branch.unlock)
 
5379
        self.add_cleanup(branch.lock_read().unlock)
5424
5380
        if revision:
5425
5381
            graph = branch.repository.get_graph()
5426
5382
            rev1, rev2 = _get_revision_range(revision, branch, self.name())
5904
5860
 
5905
5861
    def run_for_list(self):
5906
5862
        tree = WorkingTree.open_containing('.')[0]
5907
 
        tree.lock_read()
5908
 
        self.add_cleanup(tree.unlock)
 
5863
        self.add_cleanup(tree.lock_read().unlock)
5909
5864
        manager = tree.get_shelf_manager()
5910
5865
        shelves = manager.active_shelves()
5911
5866
        if len(shelves) == 0: