~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-07-09 13:58:59 UTC
  • mfrom: (3533.2.1 jam-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080709135859-wq3r1d1fjcafelgw
(jam) (bug #243536) tsort.merge_sorted() can ignore ghosts in the
        mainline history passed in.

Show diffs side-by-side

added added

removed removed

Lines of Context:
721
721
                    ' directory exists, but does not already'
722
722
                    ' have a control directory.  This flag will'
723
723
                    ' allow push to proceed.'),
724
 
        Option('reference',
725
 
            help='Create a stacked branch that refers to another branch '
726
 
                'for the commit history. Only the work not present in the '
727
 
                'referenced branch is included in the branch created.',
728
 
            type=unicode),
729
 
        Option('stacked',
730
 
            help='Create a stacked branch that references the public location '
731
 
                'of the parent branch. See --reference for more information.'),
732
724
        ]
733
725
    takes_args = ['location?']
734
726
    encoding_type = 'replace'
735
727
 
736
728
    def run(self, location=None, remember=False, overwrite=False,
737
 
        create_prefix=False, verbose=False, revision=None,
738
 
        use_existing_dir=False, directory=None, reference=None, stacked=False):
739
 
        from bzrlib.push import _show_push_branch
740
 
 
741
 
        # Get the source branch and revision_id
 
729
            create_prefix=False, verbose=False, revision=None,
 
730
            use_existing_dir=False,
 
731
            directory=None):
 
732
        # FIXME: Way too big!  Put this into a function called from the
 
733
        # command.
742
734
        if directory is None:
743
735
            directory = '.'
744
736
        br_from = Branch.open_containing(directory)[0]
 
737
        stored_loc = br_from.get_push_location()
 
738
        if location is None:
 
739
            if stored_loc is None:
 
740
                raise errors.BzrCommandError("No push location known or specified.")
 
741
            else:
 
742
                display_url = urlutils.unescape_for_display(stored_loc,
 
743
                        self.outf.encoding)
 
744
                self.outf.write("Using saved location: %s\n" % display_url)
 
745
                location = stored_loc
 
746
 
 
747
        to_transport = transport.get_transport(location)
 
748
 
 
749
        br_to = repository_to = dir_to = None
 
750
        try:
 
751
            dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
 
752
        except errors.NotBranchError:
 
753
            pass # Didn't find anything
 
754
        else:
 
755
            # If we can open a branch, use its direct repository, otherwise see
 
756
            # if there is a repository without a branch.
 
757
            try:
 
758
                br_to = dir_to.open_branch()
 
759
            except errors.NotBranchError:
 
760
                # Didn't find a branch, can we find a repository?
 
761
                try:
 
762
                    repository_to = dir_to.find_repository()
 
763
                except errors.NoRepositoryPresent:
 
764
                    pass
 
765
            else:
 
766
                # Found a branch, so we must have found a repository
 
767
                repository_to = br_to.repository
 
768
 
745
769
        if revision is not None:
746
770
            if len(revision) == 1:
747
771
                revision_id = revision[0].in_history(br_from).rev_id
751
775
        else:
752
776
            revision_id = br_from.last_revision()
753
777
 
754
 
        # Get the reference branch, if any
755
 
        if reference is not None:
756
 
            reference = urlutils.normalize_url(reference)
757
 
        elif stacked:
758
 
            reference = None
759
 
            parent_url = br_from.get_parent()
760
 
            if parent_url:
761
 
                parent = Branch.open(parent_url)
762
 
                reference = parent.get_public_branch()
763
 
                if not reference:
764
 
                    # I considered excluding non-http url's here, thus forcing
765
 
                    # 'public' branches only, but that only works for some
766
 
                    # users, so it's best to just depend on the user spotting an
767
 
                    # error by the feedback given to them. RBC 20080227.
768
 
                    reference = parent_url
769
 
            if not reference:
770
 
                raise errors.BzrCommandError(
771
 
                    "Could not determine branch to refer to.")
772
 
 
773
 
        # Get the destination location
774
 
        if location is None:
775
 
            stored_loc = br_from.get_push_location()
776
 
            if stored_loc is None:
777
 
                raise errors.BzrCommandError(
778
 
                    "No push location known or specified.")
779
 
            else:
780
 
                display_url = urlutils.unescape_for_display(stored_loc,
781
 
                        self.outf.encoding)
782
 
                self.outf.write("Using saved location: %s\n" % display_url)
783
 
                location = stored_loc
784
 
 
785
 
        _show_push_branch(br_from, revision_id, location, self.outf,
786
 
            verbose=verbose, overwrite=overwrite, remember=remember,
787
 
            reference=reference, create_prefix=create_prefix,
788
 
            use_existing_dir=use_existing_dir)
 
778
        push_result = None
 
779
        if verbose:
 
780
            old_rh = []
 
781
        if dir_to is None:
 
782
            # The destination doesn't exist; create it.
 
783
            # XXX: Refactor the create_prefix/no_create_prefix code into a
 
784
            #      common helper function
 
785
 
 
786
            def make_directory(transport):
 
787
                transport.mkdir('.')
 
788
                return transport
 
789
 
 
790
            def redirected(redirected_transport, e, redirection_notice):
 
791
                return transport.get_transport(e.get_target_url())
 
792
 
 
793
            try:
 
794
                to_transport = transport.do_catching_redirections(
 
795
                    make_directory, to_transport, redirected)
 
796
            except errors.FileExists:
 
797
                if not use_existing_dir:
 
798
                    raise errors.BzrCommandError("Target directory %s"
 
799
                         " already exists, but does not have a valid .bzr"
 
800
                         " directory. Supply --use-existing-dir to push"
 
801
                         " there anyway." % location)
 
802
            except errors.NoSuchFile:
 
803
                if not create_prefix:
 
804
                    raise errors.BzrCommandError("Parent directory of %s"
 
805
                        " does not exist."
 
806
                        "\nYou may supply --create-prefix to create all"
 
807
                        " leading parent directories."
 
808
                        % location)
 
809
                _create_prefix(to_transport)
 
810
            except errors.TooManyRedirections:
 
811
                raise errors.BzrCommandError("Too many redirections trying "
 
812
                                             "to make %s." % location)
 
813
 
 
814
            # Now the target directory exists, but doesn't have a .bzr
 
815
            # directory. So we need to create it, along with any work to create
 
816
            # all of the dependent branches, etc.
 
817
            dir_to = br_from.bzrdir.clone_on_transport(to_transport,
 
818
                                                       revision_id=revision_id)
 
819
            br_to = dir_to.open_branch()
 
820
            # TODO: Some more useful message about what was copied
 
821
            note('Created new branch.')
 
822
            # We successfully created the target, remember it
 
823
            if br_from.get_push_location() is None or remember:
 
824
                br_from.set_push_location(br_to.base)
 
825
        elif repository_to is None:
 
826
            # we have a bzrdir but no branch or repository
 
827
            # XXX: Figure out what to do other than complain.
 
828
            raise errors.BzrCommandError("At %s you have a valid .bzr control"
 
829
                " directory, but not a branch or repository. This is an"
 
830
                " unsupported configuration. Please move the target directory"
 
831
                " out of the way and try again."
 
832
                % location)
 
833
        elif br_to is None:
 
834
            # We have a repository but no branch, copy the revisions, and then
 
835
            # create a branch.
 
836
            repository_to.fetch(br_from.repository, revision_id=revision_id)
 
837
            br_to = br_from.clone(dir_to, revision_id=revision_id)
 
838
            note('Created new branch.')
 
839
            if br_from.get_push_location() is None or remember:
 
840
                br_from.set_push_location(br_to.base)
 
841
        else: # We have a valid to branch
 
842
            # We were able to connect to the remote location, so remember it
 
843
            # we don't need to successfully push because of possible divergence.
 
844
            if br_from.get_push_location() is None or remember:
 
845
                br_from.set_push_location(br_to.base)
 
846
            if verbose:
 
847
                old_rh = br_to.revision_history()
 
848
            try:
 
849
                try:
 
850
                    tree_to = dir_to.open_workingtree()
 
851
                except errors.NotLocalUrl:
 
852
                    warning("This transport does not update the working " 
 
853
                            "tree of: %s. See 'bzr help working-trees' for "
 
854
                            "more information." % br_to.base)
 
855
                    push_result = br_from.push(br_to, overwrite,
 
856
                                               stop_revision=revision_id)
 
857
                except errors.NoWorkingTree:
 
858
                    push_result = br_from.push(br_to, overwrite,
 
859
                                               stop_revision=revision_id)
 
860
                else:
 
861
                    tree_to.lock_write()
 
862
                    try:
 
863
                        push_result = br_from.push(tree_to.branch, overwrite,
 
864
                                                   stop_revision=revision_id)
 
865
                        tree_to.update()
 
866
                    finally:
 
867
                        tree_to.unlock()
 
868
            except errors.DivergedBranches:
 
869
                raise errors.BzrCommandError('These branches have diverged.'
 
870
                                        '  Try using "merge" and then "push".')
 
871
        if push_result is not None:
 
872
            push_result.report(self.outf)
 
873
        elif verbose:
 
874
            new_rh = br_to.revision_history()
 
875
            if old_rh != new_rh:
 
876
                # Something changed
 
877
                from bzrlib.log import show_changed_revisions
 
878
                show_changed_revisions(br_to, old_rh, new_rh,
 
879
                                       to_file=self.outf)
 
880
        else:
 
881
            # we probably did a clone rather than a push, so a message was
 
882
            # emitted above
 
883
            pass
789
884
 
790
885
 
791
886
class cmd_branch(Command):
805
900
    _see_also = ['checkout']
806
901
    takes_args = ['from_location', 'to_location?']
807
902
    takes_options = ['revision', Option('hardlink',
808
 
        help='Hard-link working tree files where possible.'),
809
 
        Option('stacked',
810
 
            help='Create a stacked branch referring to the source branch. '
811
 
                'The new branch will depend on the availability of the source '
812
 
                'branch for all operations.'),
813
 
        ]
 
903
        help='Hard-link working tree files where possible.')]
814
904
    aliases = ['get', 'clone']
815
905
 
816
906
    def run(self, from_location, to_location=None, revision=None,
817
 
            hardlink=False, stacked=False):
 
907
            hardlink=False):
818
908
        from bzrlib.tag import _merge_tags_if_possible
819
909
        if revision is None:
820
910
            revision = [None]
849
939
                dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
850
940
                                            possible_transports=[to_transport],
851
941
                                            accelerator_tree=accelerator_tree,
852
 
                                            hardlink=hardlink, stacked=stacked)
 
942
                                            hardlink=hardlink)
853
943
                branch = dir.open_branch()
854
944
            except errors.NoSuchRevision:
855
945
                to_transport.delete_tree('.')
856
 
                msg = "The branch %s has no revision %s." % (from_location,
857
 
                    revision[0])
 
946
                msg = "The branch %s has no revision %s." % (from_location, revision[0])
858
947
                raise errors.BzrCommandError(msg)
859
948
            _merge_tags_if_possible(br_from, branch)
860
 
            # If the source branch is stacked, the new branch may
861
 
            # be stacked whether we asked for that explicitly or not.
862
 
            # We therefore need a try/except here and not just 'if stacked:'
863
 
            try:
864
 
                note('Created new stacked branch referring to %s.' %
865
 
                    branch.get_stacked_on())
866
 
            except (errors.NotStacked, errors.UnstackableBranchFormat,
867
 
                errors.UnstackableRepositoryFormat), e:
868
 
                note('Branched %d revision(s).' % branch.revno())
 
949
            note('Branched %d revision(s).' % branch.revno())
869
950
        finally:
870
951
            br_from.unlock()
871
952