~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Aaron Bentley
  • Date: 2007-02-14 21:57:40 UTC
  • mfrom: (2286 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2288.
  • Revision ID: abentley@panoramicfeedback.com-20070214215740-qehopznuc8to99oy
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
537
537
    location can be accessed.
538
538
    """
539
539
 
540
 
    takes_options = ['remember', 'overwrite', 'revision', 'verbose']
 
540
    takes_options = ['remember', 'overwrite', 'revision', 'verbose',
 
541
        Option('directory',
 
542
            help='branch to pull into, '
 
543
                 'rather than the one containing the working directory',
 
544
            short_name='d',
 
545
            type=unicode,
 
546
            ),
 
547
        ]
541
548
    takes_args = ['location?']
542
549
    encoding_type = 'replace'
543
550
 
544
551
    def run(self, location=None, remember=False, overwrite=False,
545
 
            revision=None, verbose=False):
 
552
            revision=None, verbose=False,
 
553
            directory=None):
546
554
        # FIXME: too much stuff is in the command class
 
555
        if directory is None:
 
556
            directory = u'.'
547
557
        try:
548
 
            tree_to = WorkingTree.open_containing(u'.')[0]
 
558
            tree_to = WorkingTree.open_containing(directory)[0]
549
559
            branch_to = tree_to.branch
550
560
        except errors.NoWorkingTree:
551
561
            tree_to = None
552
 
            branch_to = Branch.open_containing(u'.')[0]
 
562
            branch_to = Branch.open_containing(directory)[0]
553
563
 
554
564
        reader = None
555
565
        if location is not None:
569
579
                self.outf.write("Using saved location: %s\n" % display_url)
570
580
                location = stored_loc
571
581
 
572
 
 
573
582
        if reader is not None:
574
583
            install_bundle(branch_to.repository, reader)
575
584
            branch_from = branch_to
632
641
    """
633
642
 
634
643
    takes_options = ['remember', 'overwrite', 'verbose',
635
 
                     Option('create-prefix', 
636
 
                            help='Create the path leading up to the branch '
637
 
                                 'if it does not already exist')]
 
644
        Option('create-prefix',
 
645
               help='Create the path leading up to the branch '
 
646
                    'if it does not already exist'),
 
647
        Option('directory',
 
648
            help='branch to push from, '
 
649
                 'rather than the one containing the working directory',
 
650
            short_name='d',
 
651
            type=unicode,
 
652
            ),
 
653
        Option('use-existing-dir',
 
654
               help='By default push will fail if the target'
 
655
                    ' directory exists, but does not already'
 
656
                    ' have a control directory. This flag will'
 
657
                    ' allow push to proceed.'),
 
658
        ]
638
659
    takes_args = ['location?']
639
660
    encoding_type = 'replace'
640
661
 
641
662
    def run(self, location=None, remember=False, overwrite=False,
642
 
            create_prefix=False, verbose=False):
 
663
            create_prefix=False, verbose=False,
 
664
            use_existing_dir=False,
 
665
            directory=None):
643
666
        # FIXME: Way too big!  Put this into a function called from the
644
667
        # command.
645
 
        
646
 
        br_from = Branch.open_containing('.')[0]
 
668
        if directory is None:
 
669
            directory = '.'
 
670
        br_from = Branch.open_containing(directory)[0]
647
671
        stored_loc = br_from.get_push_location()
648
672
        if location is None:
649
673
            if stored_loc is None:
658
682
        location_url = to_transport.base
659
683
 
660
684
        old_rh = []
 
685
        count = 0
 
686
 
 
687
        br_to = repository_to = dir_to = None
661
688
        try:
662
 
            dir_to = bzrdir.BzrDir.open(location_url)
663
 
            br_to = dir_to.open_branch()
 
689
            dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
664
690
        except errors.NotBranchError:
665
 
            # create a branch.
666
 
            to_transport = to_transport.clone('..')
667
 
            if not create_prefix:
 
691
            pass # Didn't find anything
 
692
        else:
 
693
            # If we can open a branch, use its direct repository, otherwise see
 
694
            # if there is a repository without a branch.
 
695
            try:
 
696
                br_to = dir_to.open_branch()
 
697
            except errors.NotBranchError:
 
698
                # Didn't find a branch, can we find a repository?
668
699
                try:
669
 
                    relurl = to_transport.relpath(location_url)
670
 
                    mutter('creating directory %s => %s', location_url, relurl)
671
 
                    to_transport.mkdir(relurl)
672
 
                except errors.NoSuchFile:
673
 
                    raise errors.BzrCommandError("Parent directory of %s "
674
 
                                                 "does not exist." % location)
 
700
                    repository_to = dir_to.find_repository()
 
701
                except errors.NoRepositoryPresent:
 
702
                    pass
675
703
            else:
676
 
                current = to_transport.base
677
 
                needed = [(to_transport, to_transport.relpath(location_url))]
 
704
                # Found a branch, so we must have found a repository
 
705
                repository_to = br_to.repository
 
706
 
 
707
        old_rh = []
 
708
        if dir_to is None:
 
709
            # XXX: Refactor the create_prefix/no_create_prefix code into a
 
710
            #      common helper function
 
711
            try:
 
712
                to_transport.mkdir('.')
 
713
            except errors.FileExists:
 
714
                if not use_existing_dir:
 
715
                    raise errors.BzrCommandError("Target directory %s"
 
716
                         " already exists, but does not have a valid .bzr"
 
717
                         " directory. Supply --use-existing-dir to push"
 
718
                         " there anyway." % location)
 
719
            except errors.NoSuchFile:
 
720
                if not create_prefix:
 
721
                    raise errors.BzrCommandError("Parent directory of %s"
 
722
                        " does not exist."
 
723
                        "\nYou may supply --create-prefix to create all"
 
724
                        " leading parent directories."
 
725
                        % location)
 
726
 
 
727
                cur_transport = to_transport
 
728
                needed = [cur_transport]
 
729
                # Recurse upwards until we can create a directory successfully
 
730
                while True:
 
731
                    new_transport = cur_transport.clone('..')
 
732
                    if new_transport.base == cur_transport.base:
 
733
                        raise errors.BzrCommandError("Failed to create path"
 
734
                                                     " prefix for %s."
 
735
                                                     % location)
 
736
                    try:
 
737
                        new_transport.mkdir('.')
 
738
                    except errors.NoSuchFile:
 
739
                        needed.append(new_transport)
 
740
                        cur_transport = new_transport
 
741
                    else:
 
742
                        break
 
743
 
 
744
                # Now we only need to create child directories
678
745
                while needed:
679
 
                    try:
680
 
                        to_transport, relpath = needed[-1]
681
 
                        to_transport.mkdir(relpath)
682
 
                        needed.pop()
683
 
                    except errors.NoSuchFile:
684
 
                        new_transport = to_transport.clone('..')
685
 
                        needed.append((new_transport,
686
 
                                       new_transport.relpath(to_transport.base)))
687
 
                        if new_transport.base == to_transport.base:
688
 
                            raise errors.BzrCommandError("Could not create "
689
 
                                                         "path prefix.")
 
746
                    cur_transport = needed.pop()
 
747
                    cur_transport.mkdir('.')
 
748
            
 
749
            # Now the target directory exists, but doesn't have a .bzr
 
750
            # directory. So we need to create it, along with any work to create
 
751
            # all of the dependent branches, etc.
690
752
            dir_to = br_from.bzrdir.clone(location_url,
691
753
                revision_id=br_from.last_revision())
692
754
            br_to = dir_to.open_branch()
694
756
            # We successfully created the target, remember it
695
757
            if br_from.get_push_location() is None or remember:
696
758
                br_from.set_push_location(br_to.base)
697
 
        else:
 
759
        elif repository_to is None:
 
760
            # we have a bzrdir but no branch or repository
 
761
            # XXX: Figure out what to do other than complain.
 
762
            raise errors.BzrCommandError("At %s you have a valid .bzr control"
 
763
                " directory, but not a branch or repository. This is an"
 
764
                " unsupported configuration. Please move the target directory"
 
765
                " out of the way and try again."
 
766
                % location)
 
767
        elif br_to is None:
 
768
            # We have a repository but no branch, copy the revisions, and then
 
769
            # create a branch.
 
770
            last_revision_id = br_from.last_revision()
 
771
            repository_to.fetch(br_from.repository,
 
772
                                revision_id=last_revision_id)
 
773
            br_to = br_from.clone(dir_to, revision_id=last_revision_id)
 
774
            count = len(br_to.revision_history())
 
775
            if br_from.get_push_location() is None or remember:
 
776
                br_from.set_push_location(br_to.base)
 
777
        else: # We have a valid to branch
698
778
            # We were able to connect to the remote location, so remember it
699
779
            # we don't need to successfully push because of possible divergence.
700
780
            if br_from.get_push_location() is None or remember:
753
833
        elif len(revision) > 1:
754
834
            raise errors.BzrCommandError(
755
835
                'bzr branch --revision takes exactly 1 revision value')
756
 
        try:
757
 
            br_from = Branch.open(from_location)
758
 
        except OSError, e:
759
 
            if e.errno == errno.ENOENT:
760
 
                raise errors.BzrCommandError('Source location "%s" does not'
761
 
                                             ' exist.' % to_location)
762
 
            else:
763
 
                raise
 
836
 
 
837
        br_from = Branch.open(from_location)
764
838
        br_from.lock_read()
765
839
        try:
766
840
            if basis is not None:
828
902
    --basis is to speed up checking out from remote branches.  When specified, it
829
903
    uses the inventory and file contents from the basis branch in preference to the
830
904
    branch being checked out.
 
905
 
 
906
    See "help checkouts" for more information on checkouts.
831
907
    """
832
908
    takes_args = ['branch_location?', 'to_location?']
833
909
    takes_options = ['revision', # , 'basis']
1124
1200
    """
1125
1201
    takes_args = ['location?']
1126
1202
    takes_options = [
1127
 
                     RegistryOption('format',
1128
 
                            help='Specify a format for this branch. See "bzr '
1129
 
                            'help formats" for details',
1130
 
                            converter=bzrdir.format_registry.make_bzrdir,
1131
 
                            registry=bzrdir.format_registry,
1132
 
                            value_switches=True, title="Branch Format"),
1133
 
                     ]
 
1203
         RegistryOption('format',
 
1204
                help='Specify a format for this branch. '
 
1205
                'See "help formats".',
 
1206
                registry=bzrdir.format_registry,
 
1207
                converter=bzrdir.format_registry.make_bzrdir,
 
1208
                value_switches=True,
 
1209
                title="Branch Format",
 
1210
                ),
 
1211
         ]
1134
1212
    def run(self, location=None, format=None):
1135
1213
        if format is None:
1136
1214
            format = bzrdir.format_registry.make_bzrdir('default')
1181
1259
        cd trunk-checkout
1182
1260
        (add files here)
1183
1261
    """
1184
 
    takes_args = ["location"] 
 
1262
    takes_args = ["location"]
1185
1263
    takes_options = [RegistryOption('format',
1186
1264
                            help='Specify a format for this repository. See'
1187
1265
                                 ' "bzr help formats" for details',
1447
1525
        if location:
1448
1526
            # find the file id to log:
1449
1527
 
1450
 
            dir, fp = bzrdir.BzrDir.open_containing(location)
1451
 
            b = dir.open_branch()
 
1528
            tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1529
                location)
1452
1530
            if fp != '':
1453
 
                try:
1454
 
                    # might be a tree:
1455
 
                    inv = dir.open_workingtree().inventory
1456
 
                except (errors.NotBranchError, errors.NotLocalUrl):
1457
 
                    # either no tree, or is remote.
1458
 
                    inv = b.basis_tree().inventory
 
1531
                if tree is None:
 
1532
                    tree = b.basis_tree()
 
1533
                inv = tree.inventory
1459
1534
                file_id = inv.path2id(fp)
1460
1535
                if file_id is None:
1461
1536
                    raise errors.BzrCommandError(
2296
2371
    default, use --remember. The value will only be saved if the remote
2297
2372
    location can be accessed.
2298
2373
 
 
2374
    The results of the merge are placed into the destination working
 
2375
    directory, where they can be reviewed (with bzr diff), tested, and then
 
2376
    committed to record the result of the merge.
 
2377
 
2299
2378
    Examples:
2300
2379
 
2301
2380
    To merge the latest revision from bzr.dev
2314
2393
    """
2315
2394
    takes_args = ['branch?']
2316
2395
    takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2317
 
                     Option('show-base', help="Show base revision text in "
2318
 
                            "conflicts"),
2319
 
                     Option('uncommitted', help='Apply uncommitted changes'
2320
 
                            ' from a working copy, instead of branch changes'),
2321
 
                     Option('pull', help='If the destination is already'
2322
 
                             ' completely merged into the source, pull from the'
2323
 
                             ' source rather than merging. When this happens,'
2324
 
                             ' you do not need to commit the result.'),
2325
 
                     ]
2326
 
 
2327
 
    def help(self):
2328
 
        from inspect import getdoc
2329
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
 
2396
        Option('show-base', help="Show base revision text in "
 
2397
               "conflicts"),
 
2398
        Option('uncommitted', help='Apply uncommitted changes'
 
2399
               ' from a working copy, instead of branch changes'),
 
2400
        Option('pull', help='If the destination is already'
 
2401
                ' completely merged into the source, pull from the'
 
2402
                ' source rather than merging. When this happens,'
 
2403
                ' you do not need to commit the result.'),
 
2404
        Option('directory',
 
2405
            help='branch to merge into, '
 
2406
                 'rather than the one containing the working directory',
 
2407
            short_name='d',
 
2408
            type=unicode,
 
2409
            ),
 
2410
    ]
2330
2411
 
2331
2412
    def run(self, branch=None, revision=None, force=False, merge_type=None,
2332
 
            show_base=False, reprocess=False, remember=False, 
2333
 
            uncommitted=False, pull=False):
 
2413
            show_base=False, reprocess=False, remember=False,
 
2414
            uncommitted=False, pull=False,
 
2415
            directory=None,
 
2416
            ):
2334
2417
        if merge_type is None:
2335
2418
            merge_type = _mod_merge.Merge3Merger
2336
2419
 
2337
 
        tree = WorkingTree.open_containing(u'.')[0]
 
2420
        if directory is None: directory = u'.'
 
2421
        tree = WorkingTree.open_containing(directory)[0]
2338
2422
        change_reporter = delta.ChangeReporter(tree.inventory)
2339
2423
 
2340
2424
        if branch is not None:
2403
2487
                    reprocess=reprocess,
2404
2488
                    show_base=show_base,
2405
2489
                    pull=pull,
2406
 
                    pb=pb,
2407
 
                    file_list=interesting_files,
 
2490
                    this_dir=directory,
 
2491
                    pb=pb, file_list=interesting_files,
2408
2492
                    change_reporter=change_reporter)
2409
2493
            finally:
2410
2494
                pb.finished()
2464
2548
                     Option('show-base', help="Show base revision text in "
2465
2549
                            "conflicts")]
2466
2550
 
2467
 
    def help(self):
2468
 
        from inspect import getdoc
2469
 
        return getdoc(self) + '\n' + _mod_merge.merge_type_help()
2470
 
 
2471
2551
    def run(self, file_list=None, merge_type=None, show_base=False,
2472
2552
            reprocess=False):
2473
2553
        if merge_type is None:
2855
2935
 
2856
2936
 
2857
2937
class cmd_bind(Command):
2858
 
    """Bind the current branch to a master branch.
2859
 
 
2860
 
    After binding, commits must succeed on the master branch
2861
 
    before they are executed on the local one.
 
2938
    """Convert the current branch into a checkout of the supplied branch.
 
2939
 
 
2940
    Once converted into a checkout, commits must succeed on the master branch
 
2941
    before they will be applied to the local branch.
 
2942
 
 
2943
    See "help checkouts" for more information on checkouts.
2862
2944
    """
2863
2945
 
2864
2946
    takes_args = ['location']
2875
2957
 
2876
2958
 
2877
2959
class cmd_unbind(Command):
2878
 
    """Unbind the current branch from its master branch.
2879
 
 
2880
 
    After unbinding, the local branch is considered independent.
2881
 
    All subsequent commits will be local.
 
2960
    """Convert the current checkout into a regular branch.
 
2961
 
 
2962
    After unbinding, the local branch is considered independent and subsequent
 
2963
    commits will be local only.
 
2964
 
 
2965
    See "help checkouts" for more information on checkouts.
2882
2966
    """
2883
2967
 
2884
2968
    takes_args = []