/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] up-to-date against bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
import bzrlib.errors as errors
31
31
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError, 
32
32
                           NotBranchError, DivergedBranches, NotConflicted,
33
 
                           NoSuchFile, NoWorkingTree)
 
33
                           NoSuchFile, NoWorkingTree, FileInWrongBranch)
34
34
from bzrlib.option import Option
35
35
from bzrlib.revisionspec import RevisionSpec
36
36
import bzrlib.trace
37
 
from bzrlib.trace import mutter, note, log_error, warning
 
37
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
38
38
from bzrlib.workingtree import WorkingTree
39
39
 
40
40
 
41
 
def branch_files(file_list, default_branch='.'):
 
41
def tree_files(file_list, default_branch='.'):
42
42
    try:
43
 
        return inner_branch_files(file_list, default_branch)
44
 
    except NotBranchError:
 
43
        return internal_tree_files(file_list, default_branch)
 
44
    except FileInWrongBranch, e:
45
45
        raise BzrCommandError("%s is not in the same branch as %s" %
46
 
                             (filename, file_list[0]))
 
46
                             (e.path, file_list[0]))
47
47
 
48
 
def inner_branch_files(file_list, default_branch='.'):
 
48
def internal_tree_files(file_list, default_branch='.'):
49
49
    """\
50
50
    Return a branch and list of branch-relative paths.
51
51
    If supplied file_list is empty or None, the branch default will be used,
52
52
    and returned file_list will match the original.
53
53
    """
54
54
    if file_list is None or len(file_list) == 0:
55
 
        return Branch.open_containing(default_branch)[0], file_list
56
 
    b = Branch.open_containing(file_list[0])[0]
57
 
    
58
 
    # note that if this is a remote branch, we would want
59
 
    # relpath against the transport. RBC 20051018
60
 
    # Most branch ops can't meaningfully operate on files in remote branches;
61
 
    # the above comment was in cmd_status.  ADHB 20051026
62
 
    tree = WorkingTree(b.base, b)
 
55
        return WorkingTree.open_containing(default_branch)[0], file_list
 
56
    tree = WorkingTree.open_containing(file_list[0])[0]
63
57
    new_list = []
64
58
    for filename in file_list:
65
 
        new_list.append(tree.relpath(filename))
66
 
    return b, new_list
 
59
        try:
 
60
            new_list.append(tree.relpath(filename))
 
61
        except NotBranchError:
 
62
            raise FileInWrongBranch(tree.branch, filename)
 
63
    return tree, new_list
67
64
 
68
65
 
69
66
# TODO: Make sure no commands unconditionally use the working directory as a
120
117
    
121
118
    @display_command
122
119
    def run(self, all=False, show_ids=False, file_list=None, revision=None):
123
 
        b, file_list = branch_files(file_list)
 
120
        tree, file_list = tree_files(file_list)
124
121
            
125
122
        from bzrlib.status import show_status
126
 
        show_status(b, show_unchanged=all, show_ids=show_ids,
 
123
        show_status(tree.branch, show_unchanged=all, show_ids=show_ids,
127
124
                    specific_files=file_list, revision=revision)
128
125
 
129
126
 
145
142
            raise BzrCommandError('You can only supply one of revision_id or --revision')
146
143
        if revision_id is None and revision is None:
147
144
            raise BzrCommandError('You must supply either --revision or a revision_id')
148
 
        b = Branch.open_containing('.')[0]
 
145
        b = WorkingTree.open_containing('.')[0].branch
149
146
        if revision_id is not None:
150
 
            sys.stdout.write(b.get_revision_xml_file(revision_id).read())
 
147
            sys.stdout.write(b.get_revision_xml(revision_id))
151
148
        elif revision is not None:
152
149
            for rev in revision:
153
150
                if rev is None:
154
151
                    raise BzrCommandError('You cannot specify a NULL revision.')
155
152
                revno, rev_id = rev.in_history(b)
156
 
                sys.stdout.write(b.get_revision_xml_file(rev_id).read())
 
153
                sys.stdout.write(b.get_revision_xml(rev_id))
157
154
    
158
155
 
159
156
class cmd_revno(Command):
183
180
        if len(revs) == 0:
184
181
            raise BzrCommandError('You must supply a revision identifier')
185
182
 
186
 
        b = Branch.open_containing('.')[0]
 
183
        b = WorkingTree.open_containing('.')[0].branch
187
184
 
188
185
        for rev in revs:
189
186
            revinfo = rev.in_history(b)
217
214
    get added when you add a file in the directory.
218
215
    """
219
216
    takes_args = ['file*']
220
 
    takes_options = ['no-recurse', 'quiet']
 
217
    takes_options = ['no-recurse']
221
218
    
222
 
    def run(self, file_list, no_recurse=False, quiet=False):
 
219
    def run(self, file_list, no_recurse=False):
223
220
        from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
224
 
        if quiet:
 
221
        if is_quiet():
225
222
            reporter = add_reporter_null
226
223
        else:
227
224
            reporter = add_reporter_print
236
233
    takes_args = ['dir+']
237
234
 
238
235
    def run(self, dir_list):
239
 
        b = None
240
 
        
241
236
        for d in dir_list:
242
237
            os.mkdir(d)
243
 
            b, dd = Branch.open_containing(d)
244
 
            b.add([dd])
 
238
            wt, dd = WorkingTree.open_containing(d)
 
239
            wt.add([dd])
245
240
            print 'added', d
246
241
 
247
242
 
252
247
    
253
248
    @display_command
254
249
    def run(self, filename):
255
 
        branch, relpath = Branch.open_containing(filename)
 
250
        tree, relpath = WorkingTree.open_containing(filename)
256
251
        print relpath
257
252
 
258
253
 
259
254
class cmd_inventory(Command):
260
 
    """Show inventory of the current working copy or a revision."""
261
 
    takes_options = ['revision', 'show-ids']
 
255
    """Show inventory of the current working copy or a revision.
 
256
 
 
257
    It is possible to limit the output to a particular entry
 
258
    type using the --kind option.  For example; --kind file.
 
259
    """
 
260
    takes_options = ['revision', 'show-ids', 'kind']
262
261
    
263
262
    @display_command
264
 
    def run(self, revision=None, show_ids=False):
265
 
        b = Branch.open_containing('.')[0]
 
263
    def run(self, revision=None, show_ids=False, kind=None):
 
264
        if kind and kind not in ['file', 'directory', 'symlink']:
 
265
            raise BzrCommandError('invalid kind specified')
 
266
        tree = WorkingTree.open_containing('.')[0]
266
267
        if revision is None:
267
 
            inv = b.working_tree().read_working_inventory()
 
268
            inv = tree.read_working_inventory()
268
269
        else:
269
270
            if len(revision) > 1:
270
271
                raise BzrCommandError('bzr inventory --revision takes'
271
272
                    ' exactly one revision identifier')
272
 
            inv = b.get_revision_inventory(revision[0].in_history(b).rev_id)
 
273
            inv = tree.branch.get_revision_inventory(
 
274
                revision[0].in_history(tree.branch).rev_id)
273
275
 
274
276
        for path, entry in inv.entries():
 
277
            if kind and kind != entry.kind:
 
278
                continue
275
279
            if show_ids:
276
280
                print '%-50s %s' % (path, entry.file_id)
277
281
            else:
288
292
    """
289
293
    takes_args = ['source$', 'dest']
290
294
    def run(self, source_list, dest):
291
 
        b, source_list = branch_files(source_list)
292
 
 
 
295
        tree, source_list = tree_files(source_list)
293
296
        # TODO: glob expansion on windows?
294
 
        tree = WorkingTree(b.base, b)
295
 
        b.move(source_list, tree.relpath(dest))
 
297
        tree.move(source_list, tree.relpath(dest))
296
298
 
297
299
 
298
300
class cmd_rename(Command):
312
314
    takes_args = ['from_name', 'to_name']
313
315
    
314
316
    def run(self, from_name, to_name):
315
 
        b, (from_name, to_name) = branch_files((from_name, to_name))
316
 
        b.rename_one(from_name, to_name)
 
317
        tree, (from_name, to_name) = tree_files((from_name, to_name))
 
318
        tree.rename_one(from_name, to_name)
317
319
 
318
320
 
319
321
class cmd_mv(Command):
333
335
    def run(self, names_list):
334
336
        if len(names_list) < 2:
335
337
            raise BzrCommandError("missing file argument")
336
 
        b, rel_names = branch_files(names_list)
 
338
        tree, rel_names = tree_files(names_list)
337
339
        
338
340
        if os.path.isdir(names_list[-1]):
339
341
            # move into existing directory
340
 
            for pair in b.move(rel_names[:-1], rel_names[-1]):
 
342
            for pair in tree.move(rel_names[:-1], rel_names[-1]):
341
343
                print "%s => %s" % pair
342
344
        else:
343
345
            if len(names_list) != 2:
344
346
                raise BzrCommandError('to mv multiple files the destination '
345
347
                                      'must be a versioned directory')
346
 
            b.rename_one(rel_names[0], rel_names[1])
 
348
            tree.rename_one(rel_names[0], rel_names[1])
347
349
            print "%s => %s" % (rel_names[0], rel_names[1])
348
350
            
349
351
    
372
374
        from bzrlib.merge import merge
373
375
        from shutil import rmtree
374
376
        import errno
375
 
        
376
 
        br_to = Branch.open_containing('.')[0]
377
 
        bound_loc = br_to.get_bound_location()
378
 
        if bound_loc:
379
 
            br = Branch.open(bound_loc)
380
 
            stored_loc = br.get_parent()
381
 
            del br
382
 
        else:
383
 
            stored_loc = br_to.get_parent()
 
377
        # FIXME: too much stuff is in the command class        
 
378
        tree_to = WorkingTree.open_containing('.')[0]
 
379
        stored_loc = tree_to.branch.get_parent()
384
380
        if location is None:
385
381
            if stored_loc is None:
386
382
                raise BzrCommandError("No pull location known or specified.")
388
384
                print "Using saved location: %s" % stored_loc
389
385
                location = stored_loc
390
386
        br_from = Branch.open(location)
 
387
        br_to = tree_to.branch
391
388
        try:
392
389
            old_rh = br_to.revision_history()
393
 
            br_to.working_tree().pull(br_from, overwrite)
 
390
            count = tree_to.pull(br_from, overwrite)
394
391
        except DivergedBranches:
 
392
            # FIXME: Just make DivergedBranches display the right message
 
393
            # itself.
395
394
            raise BzrCommandError("These branches have diverged."
396
395
                                  "  Try merge.")
397
396
        if br_to.get_parent() is None or remember:
398
397
            br_to.set_parent(location)
399
 
 
 
398
        note('%d revision(s) pulled.', count)
400
399
        if verbose:
401
 
            new_rh = br_to.revision_history()
 
400
            new_rh = tree_to.branch.revision_history()
402
401
            if old_rh != new_rh:
403
402
                # Something changed
404
403
                from bzrlib.log import show_changed_revisions
405
 
                show_changed_revisions(br_to, old_rh, new_rh)
 
404
                show_changed_revisions(tree_to.branch, old_rh, new_rh)
406
405
 
407
406
 
408
407
class cmd_push(Command):
436
435
 
437
436
    def run(self, location=None, remember=False, overwrite=False,
438
437
            create_prefix=False, verbose=False):
 
438
        # FIXME: Way too big!  Put this into a function called from the
 
439
        # command.
439
440
        import errno
440
441
        from shutil import rmtree
441
442
        from bzrlib.transport import get_transport
442
443
        
443
 
        br_from = Branch.open_containing('.')[0]
444
 
        stored_loc = br_from.get_push_location()
 
444
        tree_from = WorkingTree.open_containing('.')[0]
 
445
        br_from = tree_from.branch
 
446
        stored_loc = tree_from.branch.get_push_location()
445
447
        if location is None:
446
448
            if stored_loc is None:
447
449
                raise BzrCommandError("No push location known or specified.")
474
476
                        if new_transport.base == transport.base:
475
477
                            raise BzrCommandError("Could not creeate "
476
478
                                                  "path prefix.")
477
 
                        
478
 
            NoSuchFile
479
479
            br_to = Branch.initialize(location)
480
480
        try:
481
481
            old_rh = br_to.revision_history()
482
 
            br_to.pull(br_from, overwrite)
 
482
            count = br_to.pull(br_from, overwrite)
483
483
        except DivergedBranches:
484
484
            raise BzrCommandError("These branches have diverged."
485
485
                                  "  Try a merge then push with overwrite.")
486
486
        if br_from.get_push_location() is None or remember:
487
487
            br_from.set_push_location(location)
488
 
 
 
488
        note('%d revision(s) pushed.' % (count,))
489
489
        if verbose:
490
490
            new_rh = br_to.revision_history()
491
491
            if old_rh != new_rh:
493
493
                from bzrlib.log import show_changed_revisions
494
494
                show_changed_revisions(br_to, old_rh, new_rh)
495
495
 
 
496
 
496
497
class cmd_branch(Command):
497
498
    """Create a new copy of a branch.
498
499
 
533
534
        br_from.lock_read()
534
535
        try:
535
536
            if basis is not None:
536
 
                basis_branch = Branch.open_containing(basis)[0]
 
537
                basis_branch = WorkingTree.open_containing(basis)[0].branch
537
538
            else:
538
539
                basis_branch = None
539
540
            if len(revision) == 1 and revision[0] is not None:
570
571
            if name:
571
572
                name = StringIO(name)
572
573
                branch.put_controlfile('branch-name', name)
 
574
            note('Branched %d revision(s).' % branch.revno())
573
575
        finally:
574
576
            br_from.unlock()
575
577
        if bound:
586
588
 
587
589
    @display_command
588
590
    def run(self, dir='.'):
589
 
        b = Branch.open_containing(dir)[0]
590
 
        old_inv = b.basis_tree().inventory
591
 
        new_inv = b.working_tree().read_working_inventory()
 
591
        tree = WorkingTree.open_containing(dir)[0]
 
592
        old_inv = tree.branch.basis_tree().inventory
 
593
        new_inv = tree.read_working_inventory()
592
594
 
593
595
        renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
594
596
        renames.sort()
603
605
    @display_command
604
606
    def run(self, branch=None):
605
607
        import info
606
 
        b = Branch.open_containing(branch)[0]
 
608
        b = WorkingTree.open_containing(branch)[0].branch
607
609
        info.show_info(b)
608
610
 
609
611
 
618
620
    aliases = ['rm']
619
621
    
620
622
    def run(self, file_list, verbose=False):
621
 
        b, file_list = branch_files(file_list)
622
 
        tree = b.working_tree()
 
623
        tree, file_list = tree_files(file_list)
623
624
        tree.remove(file_list, verbose=verbose)
624
625
 
625
626
 
634
635
    takes_args = ['filename']
635
636
    @display_command
636
637
    def run(self, filename):
637
 
        b, relpath = Branch.open_containing(filename)
638
 
        i = b.working_tree().inventory.path2id(relpath)
 
638
        tree, relpath = WorkingTree.open_containing(filename)
 
639
        i = tree.inventory.path2id(relpath)
639
640
        if i == None:
640
641
            raise BzrError("%r is not a versioned file" % filename)
641
642
        else:
651
652
    takes_args = ['filename']
652
653
    @display_command
653
654
    def run(self, filename):
654
 
        b, relpath = Branch.open_containing(filename)
655
 
        inv = b.inventory
 
655
        tree, relpath = WorkingTree.open_containing(filename)
 
656
        inv = tree.inventory
656
657
        fid = inv.path2id(relpath)
657
658
        if fid == None:
658
659
            raise BzrError("%r is not a versioned file" % filename)
665
666
    hidden = True
666
667
    @display_command
667
668
    def run(self):
668
 
        for patchid in Branch.open_containing('.')[0].revision_history():
 
669
        branch = WorkingTree.open_containing('.')[0].branch
 
670
        for patchid in branch.revision_history():
669
671
            print patchid
670
672
 
671
673
 
674
676
    hidden = True
675
677
    @display_command
676
678
    def run(self):
677
 
        b = Branch.open_containing('.')[0]
 
679
        tree = WorkingTree.open_containing('.')[0]
 
680
        b = tree.branch
 
681
        # FIXME. should be tree.last_revision
678
682
        for revision_id in b.get_ancestry(b.last_revision()):
679
683
            print revision_id
680
684
 
681
685
 
682
 
class cmd_directories(Command):
683
 
    """Display list of versioned directories in this branch."""
684
 
    @display_command
685
 
    def run(self):
686
 
        for name, ie in (Branch.open_containing('.')[0].working_tree().
687
 
                         read_working_inventory().directories()):
688
 
            if name == '':
689
 
                print '.'
690
 
            else:
691
 
                print name
692
 
 
693
 
 
694
686
class cmd_init(Command):
695
687
    """Make a directory into a versioned branch.
696
688
 
753
745
    def run(self, revision=None, file_list=None, diff_options=None):
754
746
        from bzrlib.diff import show_diff
755
747
        try:
756
 
            b, file_list = inner_branch_files(file_list)
 
748
            tree, file_list = internal_tree_files(file_list)
 
749
            b = None
757
750
            b2 = None
758
 
        except NotBranchError:
 
751
        except FileInWrongBranch:
759
752
            if len(file_list) != 2:
760
753
                raise BzrCommandError("Files are in different branches")
761
754
 
762
755
            b, file1 = Branch.open_containing(file_list[0])
763
756
            b2, file2 = Branch.open_containing(file_list[1])
764
757
            if file1 != "" or file2 != "":
 
758
                # FIXME diff those two files. rbc 20051123
765
759
                raise BzrCommandError("Files are in different branches")
766
760
            file_list = None
767
761
        if revision is not None:
768
762
            if b2 is not None:
769
763
                raise BzrCommandError("Can't specify -r with two branches")
770
764
            if len(revision) == 1:
771
 
                return show_diff(b, revision[0], specific_files=file_list,
 
765
                return show_diff(tree.branch, revision[0], specific_files=file_list,
772
766
                                 external_diff_options=diff_options)
773
767
            elif len(revision) == 2:
774
 
                return show_diff(b, revision[0], specific_files=file_list,
 
768
                return show_diff(tree.branch, revision[0], specific_files=file_list,
775
769
                                 external_diff_options=diff_options,
776
770
                                 revision2=revision[1])
777
771
            else:
778
772
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
779
773
        else:
780
 
            return show_diff(b, None, specific_files=file_list,
781
 
                             external_diff_options=diff_options, b2=b2)
 
774
            if b is not None:
 
775
                return show_diff(b, None, specific_files=file_list,
 
776
                                 external_diff_options=diff_options, b2=b2)
 
777
            else:
 
778
                return show_diff(tree.branch, None, specific_files=file_list,
 
779
                                 external_diff_options=diff_options)
782
780
 
783
781
 
784
782
class cmd_deleted(Command):
792
790
    # if the directories are very large...)
793
791
    @display_command
794
792
    def run(self, show_ids=False):
795
 
        b = Branch.open_containing('.')[0]
796
 
        old = b.basis_tree()
797
 
        new = b.working_tree()
 
793
        tree = WorkingTree.open_containing('.')[0]
 
794
        old = tree.branch.basis_tree()
798
795
        for path, ie in old.inventory.iter_entries():
799
 
            if not new.has_id(ie.file_id):
 
796
            if not tree.has_id(ie.file_id):
800
797
                if show_ids:
801
798
                    print '%-50s %s' % (path, ie.file_id)
802
799
                else:
810
807
    def run(self):
811
808
        from bzrlib.delta import compare_trees
812
809
 
813
 
        b = Branch.open_containing('.')[0]
814
 
        td = compare_trees(b.basis_tree(), b.working_tree())
 
810
        tree = WorkingTree.open_containing('.')[0]
 
811
        td = compare_trees(tree.branch.basis_tree(), tree)
815
812
 
816
813
        for path, id, kind, text_modified, meta_modified in td.modified:
817
814
            print path
823
820
    hidden = True
824
821
    @display_command
825
822
    def run(self):
826
 
        b = Branch.open_containing('.')[0]
827
 
        wt = b.working_tree()
828
 
        basis_inv = b.basis_tree().inventory
 
823
        wt = WorkingTree.open_containing('.')[0]
 
824
        basis_inv = wt.branch.basis_tree().inventory
829
825
        inv = wt.inventory
830
826
        for file_id in inv:
831
827
            if file_id in basis_inv:
846
842
    @display_command
847
843
    def run(self, filename=None):
848
844
        """Print the branch root."""
849
 
        b = Branch.open_containing(filename)[0]
850
 
        print b.base
 
845
        tree = WorkingTree.open_containing(filename)[0]
 
846
        print tree.basedir
851
847
 
852
848
 
853
849
class cmd_log(Command):
889
885
        direction = (forward and 'forward') or 'reverse'
890
886
        
891
887
        if filename:
892
 
            b, fp = Branch.open_containing(filename)
 
888
            # might be a tree:
 
889
            tree = None
 
890
            try:
 
891
                tree, fp = WorkingTree.open_containing(filename)
 
892
                b = tree.branch
 
893
                if fp != '':
 
894
                    inv = tree.read_working_inventory()
 
895
            except NotBranchError:
 
896
                pass
 
897
            if tree is None:
 
898
                b, fp = Branch.open_containing(filename)
 
899
                if fp != '':
 
900
                    inv = b.get_inventory(b.last_revision())
893
901
            if fp != '':
894
 
                try:
895
 
                    inv = b.working_tree().read_working_inventory()
896
 
                except NoWorkingTree:
897
 
                    inv = b.get_inventory(b.last_revision())
898
902
                file_id = inv.path2id(fp)
899
903
            else:
900
904
                file_id = None  # points to branch root
901
905
        else:
902
 
            b, relpath = Branch.open_containing('.')
 
906
            tree, relpath = WorkingTree.open_containing('.')
 
907
            b = tree.branch
903
908
            file_id = None
904
909
 
905
910
        if revision is None:
913
918
        else:
914
919
            raise BzrCommandError('bzr log --revision takes one or two values.')
915
920
 
916
 
        if rev1 == 0:
917
 
            rev1 = None
918
 
        if rev2 == 0:
919
 
            rev2 = None
 
921
        # By this point, the revision numbers are converted to the +ve
 
922
        # form if they were supplied in the -ve form, so we can do
 
923
        # this comparison in relative safety
 
924
        if rev1 > rev2:
 
925
            (rev2, rev1) = (rev1, rev2)
920
926
 
921
927
        mutter('encoding log as %r', bzrlib.user_encoding)
922
928
 
953
959
    takes_args = ["filename"]
954
960
    @display_command
955
961
    def run(self, filename):
956
 
        b, relpath = Branch.open_containing(filename)[0]
957
 
        inv = b.working_tree().read_working_inventory()
 
962
        tree, relpath = WorkingTree.open_containing(filename)
 
963
        b = tree.branch
 
964
        inv = tree.read_working_inventory()
958
965
        file_id = inv.path2id(relpath)
959
966
        for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
960
967
            print "%6d %s" % (revno, what)
988
995
 
989
996
        selection = {'I':ignored, '?':unknown, 'V':versioned}
990
997
 
991
 
        b, relpath = Branch.open_containing('.')
 
998
        tree, relpath = WorkingTree.open_containing('.')
992
999
        if from_root:
993
1000
            relpath = ''
994
1001
        elif relpath:
995
1002
            relpath += '/'
996
 
        if revision == None:
997
 
            tree = b.working_tree()
998
 
        else:
999
 
            tree = b.revision_tree(revision[0].in_history(b).rev_id)
 
1003
        if revision is not None:
 
1004
            tree = tree.branch.revision_tree(
 
1005
                revision[0].in_history(tree.branch).rev_id)
1000
1006
        for fp, fc, kind, fid, entry in tree.list_files():
1001
1007
            if fp.startswith(relpath):
1002
1008
                fp = fp[len(relpath):]
1015
1021
                    print fp
1016
1022
 
1017
1023
 
1018
 
 
1019
1024
class cmd_unknowns(Command):
1020
1025
    """List unknown files."""
1021
1026
    @display_command
1022
1027
    def run(self):
1023
1028
        from bzrlib.osutils import quotefn
1024
 
        for f in Branch.open_containing('.')[0].unknowns():
 
1029
        for f in WorkingTree.open_containing('.')[0].unknowns():
1025
1030
            print quotefn(f)
1026
1031
 
1027
1032
 
1028
 
 
1029
1033
class cmd_ignore(Command):
1030
1034
    """Ignore a command or pattern.
1031
1035
 
1051
1055
        from bzrlib.atomicfile import AtomicFile
1052
1056
        import os.path
1053
1057
 
1054
 
        b, relpath = Branch.open_containing('.')
1055
 
        ifn = b.abspath('.bzrignore')
 
1058
        tree, relpath = WorkingTree.open_containing('.')
 
1059
        ifn = tree.abspath('.bzrignore')
1056
1060
 
1057
1061
        if os.path.exists(ifn):
1058
1062
            f = open(ifn, 'rt')
1077
1081
        finally:
1078
1082
            f.close()
1079
1083
 
1080
 
        inv = b.working_tree().inventory
 
1084
        inv = tree.inventory
1081
1085
        if inv.path2id('.bzrignore'):
1082
1086
            mutter('.bzrignore is already versioned')
1083
1087
        else:
1084
1088
            mutter('need to make new .bzrignore file versioned')
1085
 
            b.add(['.bzrignore'])
1086
 
 
 
1089
            tree.add(['.bzrignore'])
1087
1090
 
1088
1091
 
1089
1092
class cmd_ignored(Command):
1092
1095
    See also: bzr ignore"""
1093
1096
    @display_command
1094
1097
    def run(self):
1095
 
        tree = Branch.open_containing('.')[0].working_tree()
 
1098
        tree = WorkingTree.open_containing('.')[0]
1096
1099
        for path, file_class, kind, file_id, entry in tree.list_files():
1097
1100
            if file_class != 'I':
1098
1101
                continue
1117
1120
        except ValueError:
1118
1121
            raise BzrCommandError("not a valid revision-number: %r" % revno)
1119
1122
 
1120
 
        print Branch.open_containing('.')[0].get_rev_id(revno)
 
1123
        print WorkingTree.open_containing('.')[0].branch.get_rev_id(revno)
1121
1124
 
1122
1125
 
1123
1126
class cmd_export(Command):
1147
1150
    def run(self, dest, revision=None, format=None, root=None):
1148
1151
        import os.path
1149
1152
        from bzrlib.export import export
1150
 
        b = Branch.open_containing('.')[0]
 
1153
        tree = WorkingTree.open_containing('.')[0]
 
1154
        b = tree.branch
1151
1155
        if revision is None:
 
1156
            # should be tree.last_revision  FIXME
1152
1157
            rev_id = b.last_revision()
1153
1158
        else:
1154
1159
            if len(revision) != 1:
1173
1178
            raise BzrCommandError("bzr cat requires a revision number")
1174
1179
        elif len(revision) != 1:
1175
1180
            raise BzrCommandError("bzr cat --revision takes exactly one number")
1176
 
        b, relpath = Branch.open_containing(filename)
 
1181
        tree = None
 
1182
        try:
 
1183
            tree, relpath = WorkingTree.open_containing(filename)
 
1184
            b = tree.branch
 
1185
        except NotBranchError:
 
1186
            pass
 
1187
        if tree is None:
 
1188
            b, relpath = Branch.open_containing(filename)
1177
1189
        b.print_file(relpath, revision[0].in_history(b).revno)
1178
1190
 
1179
1191
 
1229
1241
        from bzrlib.status import show_status
1230
1242
        from cStringIO import StringIO
1231
1243
 
1232
 
        b, selected_list = branch_files(selected_list)
 
1244
        tree, selected_list = tree_files(selected_list)
1233
1245
        if message is None and not file:
1234
1246
            catcher = StringIO()
1235
 
            show_status(b, specific_files=selected_list,
 
1247
            show_status(tree.branch, specific_files=selected_list,
1236
1248
                        to_file=catcher)
1237
1249
            message = edit_commit_message(catcher.getvalue())
1238
1250
 
1250
1262
                raise BzrCommandError("empty commit message specified")
1251
1263
            
1252
1264
        try:
1253
 
            b.working_tree().commit(message, specific_files=selected_list,
1254
 
                     allow_pointless=unchanged, strict=strict)
 
1265
            tree.commit(message, specific_files=selected_list,
 
1266
                        allow_pointless=unchanged, strict=strict)
1255
1267
        except PointlessCommit:
1256
1268
            # FIXME: This should really happen before the file is read in;
1257
1269
            # perhaps prepare the commit; get the message; then actually commit
1266
1278
        except errors.CannotInstallRevisions, e:
1267
1279
            raise BzrCommandError(e.msg)
1268
1280
 
 
1281
        note('Committed revision %d.' % (tree.branch.revno(),))
 
1282
 
1269
1283
 
1270
1284
class cmd_check(Command):
1271
1285
    """Validate consistency of branch history.
1278
1292
 
1279
1293
    def run(self, dir='.', verbose=False):
1280
1294
        from bzrlib.check import check
1281
 
        check(Branch.open_containing(dir)[0], verbose)
 
1295
        check(WorkingTree.open_containing(dir)[0].branch, verbose)
1282
1296
 
1283
1297
 
1284
1298
class cmd_scan_cache(Command):
1324
1338
    @display_command
1325
1339
    def run(self, email=False):
1326
1340
        try:
1327
 
            b = bzrlib.branch.Branch.open_containing('.')[0]
 
1341
            b = WorkingTree.open_containing('.')[0].branch
1328
1342
            config = bzrlib.config.BranchConfig(b)
1329
1343
        except NotBranchError:
1330
1344
            config = bzrlib.config.GlobalConfig()
1375
1389
    def run(self, testspecs_list=None, verbose=False, one=False,
1376
1390
            keep_output=False):
1377
1391
        import bzrlib.ui
1378
 
        from bzrlib.selftest import selftest
 
1392
        from bzrlib.tests import selftest
1379
1393
        # we don't want progress meters from the tests to go to the
1380
1394
        # real output; and we don't want log messages cluttering up
1381
1395
        # the real logs.
1507
1521
        if merge_type is None:
1508
1522
            merge_type = ApplyMerge3
1509
1523
        if branch is None:
1510
 
            branch = Branch.open_containing('.')[0].get_parent()
 
1524
            branch = WorkingTree.open_containing('.')[0].branch.get_parent()
1511
1525
            if branch is None:
1512
1526
                raise BzrCommandError("No merge location known or specified.")
1513
1527
            else:
1563
1577
        from bzrlib.merge_core import ApplyMerge3
1564
1578
        if merge_type is None:
1565
1579
            merge_type = ApplyMerge3
1566
 
        b, file_list = branch_files(file_list)
1567
 
        b.lock_write()
 
1580
        tree, file_list = tree_files(file_list)
 
1581
        tree.lock_write()
1568
1582
        try:
1569
 
            pending_merges = b.working_tree().pending_merges() 
 
1583
            pending_merges = tree.pending_merges() 
1570
1584
            if len(pending_merges) != 1:
1571
1585
                raise BzrCommandError("Sorry, remerge only works after normal"
1572
1586
                                      + " merges.  Not cherrypicking or"
1573
1587
                                      + "multi-merges.")
1574
 
            this_tree = b.working_tree()
1575
 
            base_revision = common_ancestor(b.last_revision(), 
1576
 
                                            pending_merges[0], b)
1577
 
            base_tree = b.revision_tree(base_revision)
1578
 
            other_tree = b.revision_tree(pending_merges[0])
 
1588
            base_revision = common_ancestor(tree.branch.last_revision(), 
 
1589
                                            pending_merges[0], tree.branch)
 
1590
            base_tree = tree.branch.revision_tree(base_revision)
 
1591
            other_tree = tree.branch.revision_tree(pending_merges[0])
1579
1592
            interesting_ids = None
1580
1593
            if file_list is not None:
1581
1594
                interesting_ids = set()
1582
1595
                for filename in file_list:
1583
 
                    file_id = this_tree.path2id(filename)
 
1596
                    file_id = tree.path2id(filename)
1584
1597
                    interesting_ids.add(file_id)
1585
 
                    if this_tree.kind(file_id) != "directory":
 
1598
                    if tree.kind(file_id) != "directory":
1586
1599
                        continue
1587
1600
                    
1588
 
                    for name, ie in this_tree.inventory.iter_entries(file_id):
 
1601
                    for name, ie in tree.inventory.iter_entries(file_id):
1589
1602
                        interesting_ids.add(ie.file_id)
1590
 
            transform_tree(this_tree, b.basis_tree(), interesting_ids)
 
1603
            transform_tree(tree, tree.branch.basis_tree(), interesting_ids)
1591
1604
            if file_list is None:
1592
 
                restore_files = list(this_tree.iter_conflicts())
 
1605
                restore_files = list(tree.iter_conflicts())
1593
1606
            else:
1594
1607
                restore_files = file_list
1595
1608
            for filename in restore_files:
1596
1609
                try:
1597
 
                    restore(this_tree.abspath(filename))
 
1610
                    restore(tree.abspath(filename))
1598
1611
                except NotConflicted:
1599
1612
                    pass
1600
 
            conflicts =  merge_inner(b, other_tree, base_tree, 
 
1613
            conflicts =  merge_inner(tree.branch, other_tree, base_tree, 
1601
1614
                                     interesting_ids = interesting_ids, 
1602
1615
                                     other_rev_id=pending_merges[0], 
1603
1616
                                     merge_type=merge_type, 
1604
1617
                                     show_base=show_base,
1605
1618
                                     reprocess=reprocess)
1606
1619
        finally:
1607
 
            b.unlock()
 
1620
            tree.unlock()
1608
1621
        if conflicts > 0:
1609
1622
            return 1
1610
1623
        else:
1631
1644
            file_list = []
1632
1645
        if revision is None:
1633
1646
            revno = -1
1634
 
            b = Branch.open_containing('.')[0]
1635
 
            rev_id = b.last_revision()
 
1647
            tree = WorkingTree.open_containing('.')[0]
 
1648
            # FIXME should be tree.last_revision
 
1649
            rev_id = tree.branch.last_revision()
1636
1650
        elif len(revision) != 1:
1637
1651
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
1638
1652
        else:
1639
 
            b, file_list = branch_files(file_list)
1640
 
            rev_id = revision[0].in_history(b).rev_id
1641
 
        b.working_tree().revert(file_list, b.revision_tree(rev_id),
 
1653
            tree, file_list = tree_files(file_list)
 
1654
            rev_id = revision[0].in_history(tree.branch).rev_id
 
1655
        tree.revert(file_list, tree.branch.revision_tree(rev_id),
1642
1656
                                not no_backup)
1643
1657
 
1644
1658
 
1709
1723
    
1710
1724
    takes_args = ['remote?']
1711
1725
    aliases = ['mis', 'miss']
1712
 
    # We don't have to add quiet to the list, because 
1713
 
    # unknown options are parsed as booleans
1714
 
    takes_options = ['verbose', 'quiet']
 
1726
    takes_options = ['verbose']
1715
1727
 
1716
1728
    @display_command
1717
 
    def run(self, remote=None, verbose=False, quiet=False):
 
1729
    def run(self, remote=None, verbose=False):
1718
1730
        from bzrlib.errors import BzrCommandError
1719
1731
        from bzrlib.missing import show_missing
1720
1732
 
1721
 
        if verbose and quiet:
 
1733
        if verbose and is_quiet():
1722
1734
            raise BzrCommandError('Cannot pass both quiet and verbose')
1723
1735
 
1724
 
        b = Branch.open_containing('.')[0]
1725
 
        parent = b.get_parent()
 
1736
        tree = WorkingTree.open_containing('.')[0]
 
1737
        parent = tree.branch.get_parent()
1726
1738
        if remote is None:
1727
1739
            if parent is None:
1728
1740
                raise BzrCommandError("No missing location known or specified.")
1729
1741
            else:
1730
 
                if not quiet:
 
1742
                if not is_quiet():
1731
1743
                    print "Using last location: %s" % parent
1732
1744
                remote = parent
1733
1745
        elif parent is None:
1734
1746
            # We only update parent if it did not exist, missing
1735
1747
            # should not change the parent
1736
 
            b.set_parent(remote)
 
1748
            tree.branch.set_parent(remote)
1737
1749
        br_remote = Branch.open_containing(remote)[0]
1738
 
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1750
        return show_missing(tree.branch, br_remote, verbose=verbose, 
 
1751
                            quiet=is_quiet())
1739
1752
 
1740
1753
 
1741
1754
class cmd_plugins(Command):
1765
1778
    @display_command
1766
1779
    def run(self, branch='.', revision=None, long=False):
1767
1780
        from bzrlib.testament import Testament
1768
 
        b = Branch.open_containing(branch)[0]
 
1781
        b = WorkingTree.open_containing(branch)[0].branch
1769
1782
        b.lock_read()
1770
1783
        try:
1771
1784
            if revision is None:
1803
1816
    @display_command
1804
1817
    def run(self, filename, all=False, long=False):
1805
1818
        from bzrlib.annotate import annotate_file
1806
 
        b, relpath = Branch.open_containing(filename)
1807
 
        b.lock_read()
 
1819
        tree, relpath = WorkingTree.open_containing(filename)
 
1820
        branch = tree.branch
 
1821
        branch.lock_read()
1808
1822
        try:
1809
 
            tree = WorkingTree(b.base, b)
1810
 
            tree = b.revision_tree(b.last_revision())
1811
1823
            file_id = tree.inventory.path2id(relpath)
 
1824
            tree = branch.revision_tree(branch.last_revision())
1812
1825
            file_version = tree.inventory[file_id].revision
1813
 
            annotate_file(b, file_version, file_id, long, all, sys.stdout)
 
1826
            annotate_file(branch, file_version, file_id, long, all, sys.stdout)
1814
1827
        finally:
1815
 
            b.unlock()
 
1828
            branch.unlock()
1816
1829
 
1817
1830
 
1818
1831
class cmd_re_sign(Command):
1830
1843
            raise BzrCommandError('You can only supply one of revision_id or --revision')
1831
1844
        if revision_id is None and revision is None:
1832
1845
            raise BzrCommandError('You must supply either --revision or a revision_id')
1833
 
        b = Branch.open_containing('.')[0]
 
1846
        b = WorkingTree.open_containing('.')[0].branch
1834
1847
        gpg_strategy = gpg.GPGStrategy(config.BranchConfig(b))
1835
1848
        if revision_id is not None:
1836
1849
            b.sign_revision(revision_id, gpg_strategy)
1911
1924
                                  "  Try merge.")
1912
1925
 
1913
1926
 
 
1927
class cmd_uncommit(bzrlib.commands.Command):
 
1928
    """Remove the last committed revision.
 
1929
 
 
1930
    By supplying the --all flag, it will not only remove the entry 
 
1931
    from revision_history, but also remove all of the entries in the
 
1932
    stores.
 
1933
 
 
1934
    --verbose will print out what is being removed.
 
1935
    --dry-run will go through all the motions, but not actually
 
1936
    remove anything.
 
1937
    
 
1938
    In the future, uncommit will create a changeset, which can then
 
1939
    be re-applied.
 
1940
    """
 
1941
    takes_options = ['all', 'verbose', 'revision',
 
1942
                    Option('dry-run', help='Don\'t actually make changes'),
 
1943
                    Option('force', help='Say yes to all questions.')]
 
1944
    takes_args = ['location?']
 
1945
    aliases = []
 
1946
 
 
1947
    def run(self, location=None, all=False,
 
1948
            dry_run=False, verbose=False,
 
1949
            revision=None, force=False):
 
1950
        from bzrlib.branch import Branch
 
1951
        from bzrlib.log import log_formatter
 
1952
        import sys
 
1953
        from bzrlib.uncommit import uncommit
 
1954
 
 
1955
        if location is None:
 
1956
            location = '.'
 
1957
        b, relpath = Branch.open_containing(location)
 
1958
 
 
1959
        if revision is None:
 
1960
            revno = b.revno()
 
1961
            rev_id = b.last_revision()
 
1962
        else:
 
1963
            revno, rev_id = revision[0].in_history(b)
 
1964
        if rev_id is None:
 
1965
            print 'No revisions to uncommit.'
 
1966
 
 
1967
        for r in range(revno, b.revno()+1):
 
1968
            rev_id = b.get_rev_id(r)
 
1969
            lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
 
1970
            lf.show(r, b.get_revision(rev_id), None)
 
1971
 
 
1972
        if dry_run:
 
1973
            print 'Dry-run, pretending to remove the above revisions.'
 
1974
            if not force:
 
1975
                val = raw_input('Press <enter> to continue')
 
1976
        else:
 
1977
            print 'The above revision(s) will be removed.'
 
1978
            if not force:
 
1979
                val = raw_input('Are you sure [y/N]? ')
 
1980
                if val.lower() not in ('y', 'yes'):
 
1981
                    print 'Canceled'
 
1982
                    return 0
 
1983
 
 
1984
        uncommit(b, remove_files=all,
 
1985
                dry_run=dry_run, verbose=verbose,
 
1986
                revno=revno)
 
1987
 
 
1988
 
1914
1989
# these get imported and then picked up by the scan for cmd_*
1915
1990
# TODO: Some more consistent way to split command definitions across files;
1916
1991
# we do need to load at least some information about them to know of