~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Ian Clatworthy
  • Date: 2008-06-06 02:20:29 UTC
  • mto: (3221.20.2 branch.shallow)
  • mto: This revision was merged to the branch mainline in revision 3537.
  • Revision ID: ian.clatworthy@canonical.com-20080606022029-oaky436994n23gpo
refactor cmd_push to use a helper function

Show diffs side-by-side

added added

removed removed

Lines of Context:
737
737
    def run(self, location=None, remember=False, overwrite=False,
738
738
        create_prefix=False, verbose=False, revision=None,
739
739
        use_existing_dir=False, directory=None, reference=None, shallow=False):
740
 
        # FIXME: Way too big!  Put this into a function called from the
741
 
        # command.
 
740
        from bzrlib.push import _show_push_branch
 
741
 
 
742
        # Get the source branch and revision_id
742
743
        if directory is None:
743
744
            directory = '.'
744
745
        br_from = Branch.open_containing(directory)[0]
745
 
        # shallow branch where to refer to logic:
 
746
        if revision is not None:
 
747
            if len(revision) == 1:
 
748
                revision_id = revision[0].in_history(br_from).rev_id
 
749
            else:
 
750
                raise errors.BzrCommandError(
 
751
                    'bzr push --revision takes one value.')
 
752
        else:
 
753
            revision_id = br_from.last_revision()
 
754
 
 
755
        # Get the reference branch, if any
746
756
        if reference is not None:
747
757
            reference = urlutils.normalize_url(reference)
748
758
        if shallow:
760
770
            if not reference:
761
771
                raise errors.BzrCommandError(
762
772
                    "Could not determine branch to refer to.")
763
 
        # where to push logic:
764
 
        stored_loc = br_from.get_push_location()
 
773
 
 
774
        # Get the destination location
765
775
        if location is None:
 
776
            stored_loc = br_from.get_push_location()
766
777
            if stored_loc is None:
767
 
                raise errors.BzrCommandError("No push location known or specified.")
 
778
                raise errors.BzrCommandError(
 
779
                    "No push location known or specified.")
768
780
            else:
769
781
                display_url = urlutils.unescape_for_display(stored_loc,
770
782
                        self.outf.encoding)
771
783
                self.outf.write("Using saved location: %s\n" % display_url)
772
784
                location = stored_loc
773
785
 
774
 
        to_transport = transport.get_transport(location)
775
 
 
776
 
        br_to = repository_to = dir_to = None
777
 
        try:
778
 
            dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
779
 
        except errors.NotBranchError:
780
 
            pass # Didn't find anything
781
 
        else:
782
 
            # If we can open a branch, use its direct repository, otherwise see
783
 
            # if there is a repository without a branch.
784
 
            try:
785
 
                br_to = dir_to.open_branch()
786
 
            except errors.NotBranchError:
787
 
                # Didn't find a branch, can we find a repository?
788
 
                try:
789
 
                    repository_to = dir_to.find_repository()
790
 
                except errors.NoRepositoryPresent:
791
 
                    pass
792
 
            else:
793
 
                # Found a branch, so we must have found a repository
794
 
                repository_to = br_to.repository
795
 
 
796
 
        if revision is not None:
797
 
            if len(revision) == 1:
798
 
                revision_id = revision[0].in_history(br_from).rev_id
799
 
            else:
800
 
                raise errors.BzrCommandError(
801
 
                    'bzr push --revision takes one value.')
802
 
        else:
803
 
            revision_id = br_from.last_revision()
804
 
 
805
 
        push_result = None
806
 
        if verbose:
807
 
            old_rh = []
808
 
        if dir_to is None:
809
 
            # The destination doesn't exist; create it.
810
 
            # XXX: Refactor the create_prefix/no_create_prefix code into a
811
 
            #      common helper function
812
 
 
813
 
            def make_directory(transport):
814
 
                transport.mkdir('.')
815
 
                return transport
816
 
 
817
 
            def redirected(redirected_transport, e, redirection_notice):
818
 
                return transport.get_transport(e.get_target_url())
819
 
 
820
 
            try:
821
 
                to_transport = transport.do_catching_redirections(
822
 
                    make_directory, to_transport, redirected)
823
 
            except errors.FileExists:
824
 
                if not use_existing_dir:
825
 
                    raise errors.BzrCommandError("Target directory %s"
826
 
                         " already exists, but does not have a valid .bzr"
827
 
                         " directory. Supply --use-existing-dir to push"
828
 
                         " there anyway." % location)
829
 
            except errors.NoSuchFile:
830
 
                if not create_prefix:
831
 
                    raise errors.BzrCommandError("Parent directory of %s"
832
 
                        " does not exist."
833
 
                        "\nYou may supply --create-prefix to create all"
834
 
                        " leading parent directories."
835
 
                        % location)
836
 
                _create_prefix(to_transport)
837
 
            except errors.TooManyRedirections:
838
 
                raise errors.BzrCommandError("Too many redirections trying "
839
 
                                             "to make %s." % location)
840
 
 
841
 
            # Now the target directory exists, but doesn't have a .bzr
842
 
            # directory. So we need to create it, along with any work to create
843
 
            # all of the dependent branches, etc.
844
 
            if reference is not None:
845
 
                # This should be buried in the clone method itself. TODO.
846
 
                try:
847
 
                    # if the from format is stackable, this will either work or
848
 
                    # trigger NotStacked. If it's not, an error will be given to
849
 
                    # the user.
850
 
                    br_from.get_stacked_on()
851
 
                except errors.NotStacked:
852
 
                    pass
853
 
                # now we need to sprout the repository,
854
 
                dir_to = br_from.bzrdir._format.initialize_on_transport(to_transport)
855
 
                br_from.repository._format.initialize(dir_to)
856
 
                br_to = br_from._format.initialize(dir_to)
857
 
                br_to.set_stacked_on(reference)
858
 
                # and copy the data up.
859
 
                br_from.push(br_to)
860
 
            else:
861
 
                dir_to = br_from.bzrdir.clone_on_transport(to_transport,
862
 
                    revision_id=revision_id)
863
 
            br_to = dir_to.open_branch()
864
 
            # TODO: Some more useful message about what was copied
865
 
            if reference is not None:
866
 
                note('Created new shallow branch referring to %s.' % reference)
867
 
            else:
868
 
                note('Created new branch.')
869
 
            # We successfully created the target, remember it
870
 
            if br_from.get_push_location() is None or remember:
871
 
                br_from.set_push_location(br_to.base)
872
 
        elif repository_to is None:
873
 
            # we have a bzrdir but no branch or repository
874
 
            # XXX: Figure out what to do other than complain.
875
 
            raise errors.BzrCommandError("At %s you have a valid .bzr control"
876
 
                " directory, but not a branch or repository. This is an"
877
 
                " unsupported configuration. Please move the target directory"
878
 
                " out of the way and try again."
879
 
                % location)
880
 
        elif br_to is None:
881
 
            # We have a repository but no branch, copy the revisions, and then
882
 
            # create a branch.
883
 
            repository_to.fetch(br_from.repository, revision_id=revision_id)
884
 
            br_to = br_from.clone(dir_to, revision_id=revision_id)
885
 
            note('Created new branch.')
886
 
            if br_from.get_push_location() is None or remember:
887
 
                br_from.set_push_location(br_to.base)
888
 
        else: # We have a valid to branch
889
 
            # We were able to connect to the remote location, so remember it
890
 
            # we don't need to successfully push because of possible divergence.
891
 
            if br_from.get_push_location() is None or remember:
892
 
                br_from.set_push_location(br_to.base)
893
 
            if verbose:
894
 
                old_rh = br_to.revision_history()
895
 
            try:
896
 
                try:
897
 
                    tree_to = dir_to.open_workingtree()
898
 
                except errors.NotLocalUrl:
899
 
                    warning("This transport does not update the working " 
900
 
                            "tree of: %s. See 'bzr help working-trees' for "
901
 
                            "more information." % br_to.base)
902
 
                    push_result = br_from.push(br_to, overwrite,
903
 
                                               stop_revision=revision_id)
904
 
                except errors.NoWorkingTree:
905
 
                    push_result = br_from.push(br_to, overwrite,
906
 
                                               stop_revision=revision_id)
907
 
                else:
908
 
                    tree_to.lock_write()
909
 
                    try:
910
 
                        push_result = br_from.push(tree_to.branch, overwrite,
911
 
                                                   stop_revision=revision_id)
912
 
                        tree_to.update()
913
 
                    finally:
914
 
                        tree_to.unlock()
915
 
            except errors.DivergedBranches:
916
 
                raise errors.BzrCommandError('These branches have diverged.'
917
 
                                        '  Try using "merge" and then "push".')
918
 
        if push_result is not None:
919
 
            push_result.report(self.outf)
920
 
        elif verbose:
921
 
            new_rh = br_to.revision_history()
922
 
            if old_rh != new_rh:
923
 
                # Something changed
924
 
                from bzrlib.log import show_changed_revisions
925
 
                show_changed_revisions(br_to, old_rh, new_rh,
926
 
                                       to_file=self.outf)
927
 
        else:
928
 
            # we probably did a clone rather than a push, so a message was
929
 
            # emitted above
930
 
            pass
 
786
        _show_push_branch(br_from, revision_id, location, self.outf,
 
787
            verbose=verbose, overwrite=overwrite, remember=remember,
 
788
            reference=reference, create_prefix=create_prefix,
 
789
            use_existing_dir=use_existing_dir)
931
790
 
932
791
 
933
792
class cmd_branch(Command):