Esempio n. 1
0
def _set_branch_location(control, to_branch, force=False):
    """Set location value of a branch reference.

    :param control: BzrDir of the checkout to change
    :param to_branch: branch that the checkout is to reference
    :param force: skip the check for local commits in a heavy checkout
    """
    branch_format = control.find_branch_format()
    if branch_format.get_reference(control) is not None:
        # Lightweight checkout: update the branch reference
        branch_format.set_reference(control, to_branch)
    else:
        b = control.open_branch()
        bound_branch = b.get_bound_location()
        if bound_branch is not None:
            # Heavyweight checkout: check all local commits
            # have been pushed to the current bound branch then
            # synchronise the local branch with the new remote branch
            # and bind to it
            possible_transports = []
            if not force and _any_local_commits(b, possible_transports):
                raise errors.BzrCommandError(
                    'Cannot switch as local commits found in the checkout. '
                    'Commit these to the bound branch or use --force to '
                    'throw them away.')
            b.set_bound_location(None)
            b.pull(to_branch,
                   overwrite=True,
                   possible_transports=possible_transports)
            b.set_bound_location(to_branch.base)
        else:
            raise errors.BzrCommandError('Cannot switch a branch, '
                                         'only a checkout.')
Esempio n. 2
0
def _show_push_branch(br_from,
                      revision_id,
                      location,
                      to_file,
                      verbose=False,
                      overwrite=False,
                      remember=False,
                      stacked_on=None,
                      create_prefix=False,
                      use_existing_dir=False,
                      no_tree=False):
    """Push a branch to a location.

    :param br_from: the source branch
    :param revision_id: the revision-id to push up to
    :param location: the url of the destination
    :param to_file: the output stream
    :param verbose: if True, display more output than normal
    :param overwrite: list of things to overwrite ("history", "tags")
        or boolean indicating for everything
    :param remember: if True, store the location as the push location for
        the source branch
    :param stacked_on: the url of the branch, if any, to stack on;
        if set, only the revisions not in that branch are pushed
    :param create_prefix: if True, create the necessary parent directories
        at the destination if they don't already exist
    :param use_existing_dir: if True, proceed even if the destination
        directory exists without a current .bzr directory in it
    """
    to_transport = transport.get_transport(location)
    try:
        dir_to = controldir.ControlDir.open_from_transport(to_transport)
    except errors.NotBranchError:
        # Didn't find anything
        dir_to = None

    if dir_to is None:
        try:
            br_to = br_from.create_clone_on_transport(
                to_transport,
                revision_id=revision_id,
                stacked_on=stacked_on,
                create_prefix=create_prefix,
                use_existing_dir=use_existing_dir,
                no_tree=no_tree)
        except errors.AlreadyControlDirError, err:
            raise errors.BzrCommandError(
                gettext(
                    "Target directory %s already contains a .bzr directory, "
                    "but it is not valid.") % (location, ))
        except errors.FileExists, err:
            if not use_existing_dir:
                raise errors.BzrCommandError(
                    gettext("Target directory %s"
                            " already exists, but does not have a .bzr"
                            " directory. Supply --use-existing-dir to push"
                            " there anyway.") % location)
            # This shouldn't occur, but if it does the FileExists error will be
            # more informative than an UnboundLocalError for br_to.
            raise
Esempio n. 3
0
def get_branch(repo, relpath, format=None):
    """Return existing branch in destination repo. Create new if don't exist.

    @param  format:     force create new branch in specified format.
    """
    repo_trans = repo.bzrdir.root_transport
    try:
        br_dir = BzrDir.open(repo_trans.abspath(relpath))
        branch = br_dir.open_branch()
    except errors.NotBranchError:
        # create destination branch directory, creating parents as needed.
        needed = [relpath]
        while needed:
            try:
                repo_trans.mkdir(needed[-1])
                needed.pop()
            except errors.NoSuchFile:
                parent = urlutils.dirname(needed[-1])
                if parent == '':
                    raise errors.BzrCommandError('Could not create branch dir')
                needed.append(parent)
        br_dir = BzrDir.create(repo_trans.abspath(relpath))
        if format is None:
            format = BranchFormat.get_default_format()
        branch = format.initialize(br_dir)

        note('Created destination branch %s' % relpath)

    if branch.repository.bzrdir.root_transport.base != repo_trans.base:
        raise errors.BzrCommandError('Branch %s does not use repository %s' %
                                     (relpath, repo_trans.base))
    # XXX: hack to make sure the branch is using the same repository
    # instance, for locking purposes
    branch.repository = repo
    return branch
Esempio n. 4
0
 def check_proposal(self):
     """Check that the submission is sensible."""
     if self.source_branch.lp.self_link == self.target_branch.lp.self_link:
         raise errors.BzrCommandError(
             'Source and target branches must be different.')
     for mp in self.source_branch.lp.landing_targets:
         if mp.queue_status in ('Merged', 'Rejected'):
             continue
         if mp.target_branch.self_link == self.target_branch.lp.self_link:
             raise errors.BzrCommandError(gettext(
                 'There is already a branch merge proposal: %s') %
                 lp_api.canonical_url(mp))
Esempio n. 5
0
  def run(self, file_list=None, revision=None, using=None,
                         diff_options=None, prefix=None):
    """
    Run the external diff tool.
    """

    # Get an instance of this tool:
    assert using is not None
    tool = find_diff_tool(using)
    tool.add_options(diff_options)
    
    # Default to current working directory:
    if (not file_list or len(file_list) == 0):
      file_list = [ osutils.getcwd() ]

    # Pick the right comparison to perform:
    if revision:
      if (len(revision) == 1) or (revision[1].spec is None):
        result = compare_using(tool, file_list, revision[0])
      elif len(revision) == 2:
        result = compare_using(tool, file_list, revision[0], revision[1])
      else:
        raise errors.BzrCommandError(
            '--revision takes exactly one or two revision specifiers')
    else:
      # Just diff against the current base tree:
      result = compare_using(tool, file_list)

    return result
Esempio n. 6
0
def _send_0_9(branch,
              revision_id,
              submit_branch,
              public_branch,
              no_patch,
              no_bundle,
              message,
              base_revision_id,
              local_target_branch=None):
    if not no_bundle:
        if not no_patch:
            patch_type = 'bundle'
        else:
            raise errors.BzrCommandError(
                gettext('Format 0.9 does not'
                        ' permit bundle with no patch'))
    else:
        if not no_patch:
            patch_type = 'diff'
        else:
            patch_type = None
    from bzrlib import merge_directive
    return merge_directive.MergeDirective.from_objects(
        branch.repository,
        revision_id,
        time.time(),
        osutils.local_time_offset(),
        submit_branch,
        public_branch=public_branch,
        patch_type=patch_type,
        message=message,
        local_target_branch=local_target_branch)
Esempio n. 7
0
    def run(self, destination=None, remember=False, overwrite=False):
        from repopush import repo_push

        # get the repository for the branch we're currently in
        bzrdir = BzrDir.open_containing('.')[0]
        try:
            branch = bzrdir.open_branch()
            src_repo = branch.repository
        except errors.NotBranchError:
            src_repo = bzrdir.open_repository()
        repo_config = LocationConfig(src_repo.bzrdir.root_transport.base)

        if destination is None:
            destination = repo_config.get_user_option('public_repository')
            if destination is None:
                raise errors.BzrCommandError('No destination specified')

        dst_repo = BzrDir.open(destination).open_repository()

        if remember or (repo_config.get_user_option('public_repository') is
                        None):
            repo_config.set_user_option('public_repository',
                                        dst_repo.bzrdir.root_transport.base)

        pb = ui_factory.nested_progress_bar()
        try:
            repo_push(src_repo, dst_repo, pb=pb, overwrite=overwrite)
        finally:
            pb.finished()
Esempio n. 8
0
 def _qbzr_run(self,
               selected_list=None,
               message=None,
               file=None,
               local=False,
               ui_mode=False,
               file_encoding=None):
     if message is not None and file:
         raise errors.BzrCommandError(
             "please specify either --message or --file")
     if file:
         f = open(file)
         try:
             message = f.read().decode(file_encoding
                                       or osutils.get_user_encoding())
         finally:
             f.close()
     tree, selected_list = WorkingTree.open_containing_paths(selected_list)
     if selected_list == ['']:
         selected_list = None
     self.main_window = CommitWindow(tree,
                                     selected_list,
                                     dialog=False,
                                     message=message,
                                     local=local,
                                     ui_mode=ui_mode)
     self.main_window.show()
     self._application.exec_()
Esempio n. 9
0
    def _load_branch(self, filename, revision):
        """To assist in getting a UI up as soon as possible, the UI calls
        back to this function to process the command-line args and convert
        them into the branch and tree etc needed by the UI.
        """
        wt, branch, relpath = \
            BzrDir.open_containing_tree_or_branch(filename)
        if wt is not None:
            wt.lock_read()
        else:
            branch.lock_read()
        try:
            if revision is None:
                if wt is not None:
                    tree = wt
                else:
                    tree = branch.repository.revision_tree(
                        branch.last_revision())
            elif len(revision) != 1:
                raise errors.BzrCommandError(
                    'bzr qannotate --revision takes exactly 1 argument')
            else:
                tree = branch.repository.revision_tree(
                    revision_id=revision[0].in_history(branch).rev_id)

            file_id = tree.path2id(relpath)
            if file_id is None:
                raise errors.NotVersionedError(filename)
            [(path, entry)
             ] = list(tree.iter_entries_by_dir(specific_file_ids=[file_id]))
            if entry.kind != 'file':
                raise errors.BzrCommandError(
                    'bzr qannotate only works for files (got %r)' % entry.kind)
            #repo = branch.repository
            #w = repo.weave_store.get_weave(file_id, repo.get_transaction())
            #content = list(w.annotate_iter(entry.revision))
            #revision_ids = set(o for o, t in content)
            #revision_ids = [o for o in revision_ids if repo.has_revision(o)]
            #revisions = branch.repository.get_revisions(revision_ids)
        finally:
            if wt is not None:
                wt.unlock()
            else:
                branch.unlock()

        return branch, tree, wt, relpath, file_id
Esempio n. 10
0
    def _qbzr_run(self, ui_mode=False, execute=False):
        from bzrlib.plugins.qbzr.lib.unbind import QBzrUnbindDialog

        branch = Branch.open_containing(CUR_DIR)[0]
        if branch.get_bound_location() == None:
            raise errors.BzrCommandError("This branch is not bound.")

        self.main_window = QBzrUnbindDialog(branch, ui_mode, execute)
        self.main_window.show()
        self._application.exec_()
Esempio n. 11
0
    def from_args(klass,
                  shelf_id=None,
                  action='apply',
                  directory='.',
                  write_diff_to=None):
        """Create an unshelver from commandline arguments.

        The returned shelver will have a tree that is locked and should
        be unlocked.

        :param shelf_id: Integer id of the shelf, as a string.
        :param action: action to perform.  May be 'apply', 'dry-run',
            'delete', 'preview'.
        :param directory: The directory to unshelve changes into.
        :param write_diff_to: See Unshelver.__init__().
        """
        tree, path = workingtree.WorkingTree.open_containing(directory)
        tree.lock_tree_write()
        try:
            manager = tree.get_shelf_manager()
            if shelf_id is not None:
                try:
                    shelf_id = int(shelf_id)
                except ValueError:
                    raise errors.InvalidShelfId(shelf_id)
            else:
                shelf_id = manager.last_shelf()
                if shelf_id is None:
                    raise errors.BzrCommandError(
                        gettext('No changes are shelved.'))
            apply_changes = True
            delete_shelf = True
            read_shelf = True
            show_diff = False
            if action == 'dry-run':
                apply_changes = False
                delete_shelf = False
            elif action == 'preview':
                apply_changes = False
                delete_shelf = False
                show_diff = True
            elif action == 'delete-only':
                apply_changes = False
                read_shelf = False
            elif action == 'keep':
                apply_changes = True
                delete_shelf = False
        except:
            tree.unlock()
            raise
        return klass(tree, manager, shelf_id, apply_changes, delete_shelf,
                     read_shelf, show_diff, write_diff_to)
Esempio n. 12
0
def repo_push(src_repo, dst_repo, pb, overwrite=False):
    src_repo.lock_read()
    try:
        dst_repo.lock_write()
        try:
            src_repo_trans = src_repo.bzrdir.root_transport
            dst_repo_trans = dst_repo.bzrdir.root_transport

            pb.update('Getting list of branches', 0, 1)
            branches = list_branches(src_repo)
            note('Pushing %d branches from %s to %s' %
                 (len(branches), src_repo_trans.base, dst_repo_trans.base))

            # XXX: ideally this would only fetch the tips of the
            # branches we found previously.
            pb.update('Fetching entire repo', 0, 1)
            dst_repo.fetch(src_repo, pb=pb)

            # Now synchronise the revision histories of the local and
            # remote branches.  The previous fetch() call has made
            # sure that the corresponding revisions exist in dst_repo.
            for index, src_branch in enumerate(branches):
                pb.update('Updating branches', index, len(branches))
                relpath = src_repo_trans.relpath(
                    src_branch.bzrdir.root_transport.base)
                format = BranchFormat.find_format(src_branch.bzrdir)
                dst_branch = get_branch(dst_repo, relpath, format)

                src_history = src_branch.revision_history()
                dst_history = dst_branch.revision_history()

                # If we aren't overwriting and the destination history
                # is not a subset of the source history, error out.
                # XXX this implementation is buggy in some cases
                if not overwrite and (src_history[:len(dst_history)] !=
                                      dst_history):
                    raise errors.BzrCommandError('Branch %s has diverged' %
                                                 relpath)

                # push tags
                src_branch.tags.merge_to(dst_branch.tags)

                if src_history != dst_history:
                    dst_branch.set_revision_history(src_history)
                    note('%d revision(s) pushed to %s' %
                         (len(src_history) - len(dst_history), relpath))
        finally:
            dst_repo.unlock()
    finally:
        src_repo.unlock()
Esempio n. 13
0
    def _authenticate(self):
        """If necessary authenticate yourself to the server."""
        if self._smtp_username is None:
            return

        if self._smtp_password is None:
            self._smtp_password = ui.ui_factory.get_password(
                'Please enter the SMTP password: %(user)s@%(host)s',
                user=self._smtp_username,
                host=self._smtp_server)
        try:
            self._connection.login(self._smtp_username, self._smtp_password)
        except smtplib.SMTPHeloError, e:
            raise errors.BzrCommandError('SMTP server refused HELO: %d %s' %
                                         (e.smtp_code, e.smtp_error))
Esempio n. 14
0
    def load(self):
        self.throbber.show()
        self.processEvents()
        try:
            if not self.tree:
                branch, relpath = Branch.open_containing(self.filename)
                self.branch = branch
                self.encoding = get_set_encoding(self.encoding, branch)
                self.encoding_selector.encoding = self.encoding

                if self.revision is None:
                    self.tree = branch.basis_tree()
                else:
                    revision_id = self.revision[0].in_branch(branch).rev_id
                    self.tree = branch.repository.revision_tree(revision_id)
                
                self.file_id = self.tree.path2id(relpath)
            
            if not self.file_id:
                self.file_id = self.tree.path2id(self.filename)
                
            if not self.file_id:
                raise errors.BzrCommandError(
                    "%r is not present in revision %s" % (
                        self.filename, self.tree.get_revision_id()))
            
            self.tree.lock_read()
            try:
                kind = self.tree.kind(self.file_id)
                if kind == 'file':
                    text = self.tree.get_file_text(self.file_id)
                elif kind == 'symlink':
                    text = self.tree.get_symlink_target(self.file_id)
                else:
                    text = ''
            finally:
                self.tree.unlock()
            self.processEvents()

            self.text = text
            self.kind = kind
            self._create_and_show_browser(self.filename, text, kind)
        finally:
            self.throbber.hide()
Esempio n. 15
0
    def _qbzr_run(self, filename, revision=None, encoding=None, native=None):
        if revision is not None and len(revision) != 1:
            raise errors.BzrCommandError("bzr qcat --revision takes exactly"
                                         " one revision specifier")

        if native:
            branch, relpath = Branch.open_containing(filename)
            if revision is None:
                tree = branch.basis_tree()
            else:
                revision_id = revision[0].in_branch(branch).rev_id
                tree = branch.repository.revision_tree(revision_id)
            result = cat_to_native_app(tree, relpath)
            return int(not result)

        window = QBzrCatWindow(filename=filename,
                               revision=revision,
                               encoding=encoding)
        window.show()
        self._application.exec_()
Esempio n. 16
0
    def _qbzr_run(self,
                  revision=None,
                  file_list=None,
                  complete=False,
                  encoding=None,
                  ignore_whitespace=False,
                  added=None,
                  deleted=None,
                  modified=None,
                  renamed=None,
                  old=None,
                  new=None,
                  ui_mode=False):

        if revision and len(revision) > 2:
            raise errors.BzrCommandError('bzr qdiff --revision takes exactly'
                                         ' one or two revision specifiers')
        # changes filter
        filter_options = FilterOptions(added=added,
                                       deleted=deleted,
                                       modified=modified,
                                       renamed=renamed)
        if not (added or deleted or modified or renamed):
            # if no filter option used then turn all on
            filter_options.all_enable()

        self.revision = revision
        self.file_list = file_list
        self.old = old
        self.new = new
        self.ignore_whitespace = ignore_whitespace

        window = DiffWindow(self,
                            complete=complete,
                            encoding=encoding,
                            filter_options=filter_options,
                            ui_mode=ui_mode)
        window.show()
        self._application.exec_()
Esempio n. 17
0
 def test_format_unicode_error(self):
     try:
         raise errors.BzrCommandError(u'argument foo\xb5 does not exist')
     except errors.BzrCommandError:
         pass
     msg = _format_exception()
Esempio n. 18
0
        if self._smtp_username is None:
            return

        if self._smtp_password is None:
            self._smtp_password = ui.ui_factory.get_password(
                'Please enter the SMTP password: %(user)s@%(host)s',
                user=self._smtp_username,
                host=self._smtp_server)
        try:
            self._connection.login(self._smtp_username, self._smtp_password)
        except smtplib.SMTPHeloError, e:
            raise errors.BzrCommandError('SMTP server refused HELO: %d %s' %
                                         (e.smtp_code, e.smtp_error))
        except smtplib.SMTPAuthenticationError, e:
            raise errors.BzrCommandError(
                'SMTP server refused authentication: %d %s' %
                (e.smtp_code, e.smtp_error))
        except smtplib.SMTPException, e:
            raise errors.BzrCommandError(str(e))

    @staticmethod
    def _split_address(address):
        """Split an username + email address into its parts.

        This takes "Joe Foo <*****@*****.**>" and returns "Joe Foo",
        "*****@*****.**".
        :param address: A combined username
        :return: (username, email)
        """
        return parseaddr(address)
Esempio n. 19
0
def show_tree_status(wt,
                     show_unchanged=None,
                     specific_files=None,
                     show_ids=False,
                     to_file=None,
                     show_pending=True,
                     revision=None,
                     short=False,
                     versioned=False):
    """Display summary of changes.

    By default this compares the working tree to a previous revision. 
    If the revision argument is given, summarizes changes between the 
    working tree and another, or between two revisions.

    The result is written out as Unicode and to_file should be able 
    to encode that.

    If showing the status of a working tree, extra information is included
    about unknown files, conflicts, and pending merges.

    :param show_unchanged: Deprecated parameter. If set, includes unchanged 
        files.
    :param specific_files: If set, a list of filenames whose status should be
        shown.  It is an error to give a filename that is not in the working 
        tree, or in the working inventory or in the basis inventory.
    :param show_ids: If set, includes each file's id.
    :param to_file: If set, write to this file (default stdout.)
    :param show_pending: If set, write pending merges.
    :param revision: If None, compare latest revision with working tree
        If not None, it must be a RevisionSpec list.
        If one revision, compare with working tree.
        If two revisions, show status between first and second.
    :param short: If True, gives short SVN-style status lines.
    :param versioned: If True, only shows versioned files.
    """
    if show_unchanged is not None:
        warn(
            "show_tree_status with show_unchanged has been deprecated "
            "since bzrlib 0.9",
            DeprecationWarning,
            stacklevel=2)

    if to_file is None:
        to_file = sys.stdout

    wt.lock_read()
    try:
        new_is_working_tree = True
        if revision is None:
            if wt.last_revision() != wt.branch.last_revision():
                warning("working tree is out of date, run 'bzr update'")
            new = wt
            old = new.basis_tree()
        elif len(revision) > 0:
            try:
                rev_id = revision[0].as_revision_id(wt.branch)
                old = wt.branch.repository.revision_tree(rev_id)
            except errors.NoSuchRevision, e:
                raise errors.BzrCommandError(str(e))
            if (len(revision) > 1) and (revision[1].spec is not None):
                try:
                    rev_id = revision[1].as_revision_id(wt.branch)
                    new = wt.branch.repository.revision_tree(rev_id)
                    new_is_working_tree = False
                except errors.NoSuchRevision, e:
                    raise errors.BzrCommandError(str(e))
            else:
    def run(self,
            acceptable_keys=None,
            revision=None,
            verbose=None,
            location=u'.'):
        bzrdir = controldir.ControlDir.open_containing(location)[0]
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config_stack()
        gpg_strategy = gpg.GPGStrategy(branch_config)

        gpg_strategy.set_acceptable_keys(acceptable_keys)

        def write(string):
            self.outf.write(string + "\n")

        def write_verbose(string):
            self.outf.write("  " + string + "\n")

        self.add_cleanup(repo.lock_read().unlock)
        #get our list of revisions
        revisions = []
        if revision is not None:
            if len(revision) == 1:
                revno, rev_id = revision[0].in_history(branch)
                revisions.append(rev_id)
            elif len(revision) == 2:
                from_revno, from_revid = revision[0].in_history(branch)
                to_revno, to_revid = revision[1].in_history(branch)
                if to_revid is None:
                    to_revno = branch.revno()
                if from_revno is None or to_revno is None:
                    raise errors.BzrCommandError(
                        gettext(
                            'Cannot verify a range of non-revision-history revisions'
                        ))
                for revno in range(from_revno, to_revno + 1):
                    revisions.append(branch.get_rev_id(revno))
        else:
            #all revisions by default including merges
            graph = repo.get_graph()
            revisions = []
            for rev_id, parents in graph.iter_ancestry(
                [branch.last_revision()]):
                if _mod_revision.is_null(rev_id):
                    continue
                if parents is None:
                    # Ignore ghosts
                    continue
                revisions.append(rev_id)
        count, result, all_verifiable = gpg.bulk_verify_signatures(
            repo, revisions, gpg_strategy)
        if all_verifiable:
            write(gettext("All commits signed with verifiable keys"))
            if verbose:
                for message in gpg.verbose_valid_message(result):
                    write_verbose(message)
            return 0
        else:
            write(gpg.valid_commits_message(count))
            if verbose:
                for message in gpg.verbose_valid_message(result):
                    write_verbose(message)
            write(gpg.expired_commit_message(count))
            if verbose:
                for message in gpg.verbose_expired_key_message(result, repo):
                    write_verbose(message)
            write(gpg.unknown_key_message(count))
            if verbose:
                for message in gpg.verbose_missing_key_message(result):
                    write_verbose(message)
            write(gpg.commit_not_valid_message(count))
            if verbose:
                for message in gpg.verbose_not_valid_message(result, repo):
                    write_verbose(message)
            write(gpg.commit_not_signed_message(count))
            if verbose:
                for message in gpg.verbose_not_signed_message(result, repo):
                    write_verbose(message)
            return 1
Esempio n. 21
0
def _parse_levels(s):
    try:
        return int(s)
    except ValueError:
        msg = "The levels argument must be an integer."
        raise errors.BzrCommandError(msg)
Esempio n. 22
0
    def run(self,
            verbose=False,
            ignore_case=False,
            no_recursive=False,
            from_root=False,
            null=False,
            levels=None,
            line_number=False,
            path_list=None,
            revision=None,
            pattern=None,
            include=None,
            exclude=None,
            fixed_string=False,
            files_with_matches=False,
            files_without_match=False,
            color=None,
            diff=False):
        from bzrlib import _termcolor
        from bzrlib.plugins.grep import (
            grep, )
        import re
        if path_list is None:
            path_list = ['.']
        else:
            if from_root:
                raise errors.BzrCommandError(
                    'cannot specify both --from-root and PATH.')

        if files_with_matches and files_without_match:
            raise errors.BzrCommandError(
                'cannot specify both '
                '-l/--files-with-matches and -L/--files-without-matches.')

        global_config = GlobalConfig()

        if color is None:
            color = global_config.get_user_option('grep_color')

        if color is None:
            color = 'never'

        if color not in ['always', 'never', 'auto']:
            raise errors.BzrCommandError('Valid values for --color are '
                                         '"always", "never" or "auto".')

        if levels == None:
            levels = 1

        print_revno = False
        if revision != None or levels == 0:
            # print revision numbers as we may be showing multiple revisions
            print_revno = True

        eol_marker = '\n'
        if null:
            eol_marker = '\0'

        if not ignore_case and grep.is_fixed_string(pattern):
            # if the pattern isalnum, implicitly use to -F for faster grep
            fixed_string = True
        elif ignore_case and fixed_string:
            # GZ 2010-06-02: Fall back to regexp rather than lowercasing
            #                pattern and text which will cause pain later
            fixed_string = False
            pattern = re.escape(pattern)

        patternc = None
        re_flags = re.MULTILINE
        if ignore_case:
            re_flags |= re.IGNORECASE

        if not fixed_string:
            patternc = grep.compile_pattern(pattern, re_flags)

        if color == 'always':
            show_color = True
        elif color == 'never':
            show_color = False
        elif color == 'auto':
            show_color = _termcolor.allow_color()

        GrepOptions.verbose = verbose
        GrepOptions.ignore_case = ignore_case
        GrepOptions.no_recursive = no_recursive
        GrepOptions.from_root = from_root
        GrepOptions.null = null
        GrepOptions.levels = levels
        GrepOptions.line_number = line_number
        GrepOptions.path_list = path_list
        GrepOptions.revision = revision
        GrepOptions.pattern = pattern
        GrepOptions.include = include
        GrepOptions.exclude = exclude
        GrepOptions.fixed_string = fixed_string
        GrepOptions.files_with_matches = files_with_matches
        GrepOptions.files_without_match = files_without_match
        GrepOptions.color = color
        GrepOptions.diff = False

        GrepOptions.eol_marker = eol_marker
        GrepOptions.print_revno = print_revno
        GrepOptions.patternc = patternc
        GrepOptions.recursive = not no_recursive
        GrepOptions.fixed_string = fixed_string
        GrepOptions.outf = self.outf
        GrepOptions.show_color = show_color

        if diff:
            # options not used:
            # files_with_matches, files_without_match
            # levels(?), line_number, from_root
            # include, exclude
            # These are silently ignored.
            grep.grep_diff(GrepOptions)
        elif revision is None:
            grep.workingtree_grep(GrepOptions)
        else:
            grep.versioned_grep(GrepOptions)
Esempio n. 23
0
def show_missing_xml(self,
                     other_branch=None,
                     reverse=False,
                     mine_only=False,
                     theirs_only=False,
                     log_format=None,
                     long=False,
                     short=False,
                     line=False,
                     show_ids=False,
                     verbose=False,
                     this=False,
                     other=False):
    """output missing info as xml"""
    if this:
        mine_only = this
    if other:
        theirs_only = other

    local_branch = Branch.open_containing(u".")[0]
    parent = local_branch.get_parent()
    if other_branch is None:
        other_branch = parent
        if other_branch is None:
            raise errors.BzrCommandError("No peer location known"
                                         " or specified.")
    display_url = urlutils.unescape_for_display(other_branch,
                                                self.outf.encoding)

    remote_branch = Branch.open(other_branch)

    if remote_branch.base == local_branch.base:
        remote_branch = local_branch
    local_branch.lock_read()
    try:
        remote_branch.lock_read()
        self.outf.write('<?xml version="1.0" encoding="%s"?>' % \
                        osutils.get_user_encoding())
        self.outf.write('<missing>')
        try:
            self.outf.write('<last_location>' + display_url + \
                            '</last_location>')
            local_extra, remote_extra = find_unmerged(local_branch,
                                                      remote_branch)
            if log_format is None:
                registry = log_formatter_registry
                log_format = registry.get_default(local_branch)
            if reverse is False:
                local_extra.reverse()
                remote_extra.reverse()
            if local_extra and not theirs_only:
                self.outf.write('<extra_revisions size="%d">' %
                                len(local_extra))

                if local_extra > 0:
                    lf = log_format(to_file=self.outf,
                                    show_ids=show_ids,
                                    show_timezone='original')
                    showlogs(
                        self,
                        iter_log_revisions(local_extra,
                                           local_branch.repository, verbose),
                        lf)
                self.outf.write('</extra_revisions>')
            if remote_extra and not mine_only:
                self.outf.write('<missing_revisions size="%d">' %
                                len(remote_extra))
                if remote_extra > 0:
                    lf = log_format(to_file=self.outf,
                                    show_ids=show_ids,
                                    show_timezone='original')
                    showlogs(
                        self,
                        iter_log_revisions(remote_extra,
                                           remote_branch.repository, verbose),
                        lf)
                self.outf.write('</missing_revisions>')
            if not remote_extra and not local_extra:
                status_code = 0
                # self.outf.write("Branches are up to date.\n")
            else:
                status_code = 1

        finally:
            remote_branch.unlock()
    finally:
        self.outf.write('</missing>')
        local_branch.unlock()

    if not status_code and parent is None and other_branch is not None:
        local_branch.lock_write()
        try:
            # handle race conditions - a parent might be set while we run.
            if local_branch.get_parent() is None:
                local_branch.set_parent(remote_branch.base)
        finally:
            local_branch.unlock()
    return status_code
Esempio n. 24
0
    :param control: BzrDir of the branch to check
    """
    try:
        tree = control.open_workingtree()
    except errors.NotBranchError, ex:
        # Lightweight checkout and branch is no longer there
        if force:
            return
        else:
            raise ex
    # XXX: Should the tree be locked for get_parent_ids?
    existing_pending_merges = tree.get_parent_ids()[1:]
    if len(existing_pending_merges) > 0:
        raise errors.BzrCommandError(
            'Pending merges must be '
            'committed or reverted before using switch.')


def _set_branch_location(control, to_branch, force=False):
    """Set location value of a branch reference.

    :param control: BzrDir of the checkout to change
    :param to_branch: branch that the checkout is to reference
    :param force: skip the check for local commits in a heavy checkout
    """
    branch_format = control.find_branch_format()
    if branch_format.get_reference(control) is not None:
        # Lightweight checkout: update the branch reference
        branch_format.set_reference(control, to_branch)
    else:
Esempio n. 25
0
def compare_using(tool, file_list=None, rev1=None, rev2=None):
  """
  Compare two branches or revisions using an external tool.
  
  Determine which revisions of the file to compare, extract them if
  necessary, and run the comparison.  Handle repository branches and
  non-local branches (see get_tree_files).
  """
  tmp_prefix = 'bzr_diff-'

  # Find the tree(s) and the files associated with each:
  (b1, work_tree1, file_ids1, remainder) = get_tree_files(file_list)
  trees_to_lock = [work_tree1]
  if (len(remainder) > 0):
    (b2, work_tree2, file_ids2, remainder) = get_tree_files(remainder)
    b2_in_working_tree = isinstance(work_tree2, workingtree.WorkingTree)
    trees_to_lock.append(work_tree2)
    if (len(remainder) > 0):
      raise errors.BzrCommandError("Cannot compare more than two branches")
    if rev1 or rev2:
      raise errors.BzrCommandError("Cannot specify -r with multiple branches")
  else:
    b2 = None
    b2_in_working_tree = False

  get_read_locks(trees_to_lock)
  try:

    kind = work_tree1.inventory.get_file_kind(file_ids1[0])
    in_subdir = (kind == 'directory' or kind == 'root_directory')
    in_working_tree = isinstance(work_tree1, workingtree.WorkingTree)
      
    # Decide which mode (tree or files) to use when writing to tmpdir:
    if (len(file_list) == 1 and not in_subdir):
      use_tree = False
    elif (b2 and not in_subdir):
      use_tree = False
    else:
      use_tree = True
  
    # Check if we need to adjust our tmpdir paths:
    if (len(file_list) == 1) or b2:
      if in_subdir:
        adjust_path = work_tree1.inventory.id2path(file_ids1[0])
      else:
        adjust_path = osutils.basename(file_list[0])
    else:
      adjust_path = ''
  
    cleanup = tool.supports('cleanup')

  finally:
    release_read_locks(trees_to_lock)

  try:
    # Use the 1st revision as the old version (basis_tree is the default):
    if rev1:
      old_tree = b1.repository.revision_tree(rev1.in_history(b1).rev_id)
      old_hint = "-rev%s" % rev1.in_history(b1).revno
    elif b2:
      old_tree = work_tree1
      old_hint = '-' + b1.nick
    else:
      old_tree = b1.basis_tree()
      old_hint = "-basis"

    get_read_locks(trees_to_lock)
    try:
      
      # Use the 2nd revision as the new version (working_tree is the default):
      if rev2:
        new_tree = b1.repository.revision_tree(rev2.in_history(b1).rev_id)
        delta = get_diffs_or_stop(old_tree, new_tree, file_ids1)
        new_hint = "-rev%s" % rev2.in_history(b1).revno
        new_tmp_dir = NamedTemporaryDir(tmp_prefix, new_hint, cleanup)
        new_tmp_dir.write_stuff(new_tree, file_ids1, use_tree)
        new_path = osutils.pathjoin(new_tmp_dir.path, adjust_path)
      elif b2_in_working_tree:
        # Files from two different branches, branch2 has a working tree:
        delta = get_diffs_or_stop(old_tree, work_tree2, file_ids2)
        if (len(file_list) == 1):
          new_path = work_tree2.id2abspath(file_ids2[0])
        else:
          new_path = work_tree2.abspath('')
      elif b2:
        # Files from two different branches, branch2 has no working tree:
        delta = get_diffs_or_stop(old_tree, work_tree2, file_ids2)
        new_hint = '-' + b2.nick
        new_tmp_dir = NamedTemporaryDir(tmp_prefix, new_hint, cleanup)
        new_tmp_dir.write_stuff(work_tree2, file_ids2, use_tree)
        new_path = osutils.pathjoin(new_tmp_dir.path, adjust_path)
      elif not in_working_tree:
        # Repository branch or remote branch, but only one revision:
        new_tree = b1.basis_tree()
        delta = get_diffs_or_stop(old_tree, new_tree, file_ids1)
        new_hint = "-basis"
        new_tmp_dir = NamedTemporaryDir(tmp_prefix, new_hint, cleanup)
        new_tmp_dir.write_stuff(new_tree, file_ids1, use_tree)
        new_path = osutils.pathjoin(new_tmp_dir.path, adjust_path)
      else:
        # Item(s) in working tree, just diff it in place:
        delta = get_diffs_or_stop(old_tree, work_tree1, file_ids1)
        if (len(file_list) == 1):
          new_path = work_tree1.id2abspath(file_ids1[0])
        else:
          new_path = work_tree1.abspath('')
  
      # No exceptions yet, so we really do need to extract the old version:
      if b2 and in_working_tree:
        if (len(file_list) == 1):
          old_path = work_tree1.id2abspath(file_ids1[0])
        else:
          old_path = work_tree1.abspath('')
      else:
        old_tmp_dir = NamedTemporaryDir(tmp_prefix, old_hint, cleanup)
        old_tmp_dir.write_stuff(old_tree, file_ids1, use_tree)
        old_path = osutils.pathjoin(old_tmp_dir.path, adjust_path)
    
    finally:
      # Release the locks before we start any interactive tools:
      release_read_locks(trees_to_lock)

    # Run the comparison:
    if (tool.supports('recursive')):
      result = tool.run(old_path, new_path)
    elif (len(file_list) == 1 and not in_subdir):
      result = tool.run(old_path, new_path)
    else:
      # Iterative diff:
      if adjust_path != '':
        path_list = [path.replace(adjust_path, '.', 1) 
            for (path, file_id, kind, text_mods, meta_mods) in delta.modified
            if text_mods]
      else:
        path_list = [path 
            for (path, file_id, kind, text_mods, meta_mods) in delta.modified
            if text_mods]
      result = tool.run(old_path, new_path, path_list)

    # Set the result, since external tools cannot be trusted to do so:
    result = 1

  except NoDifferencesFound:
    result = 0

  return result
Esempio n. 26
0
    def refresh_view(self):
        """get the revisions wanted by the user, do the verifications and
        popular the tree widget with the results"""
        self.throbber.show()
        bzrdir = _mod_bzrdir.BzrDir.open_containing(self.location)[0]
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config()
        gpg_strategy = gpg.GPGStrategy(branch_config)
        gpg_strategy.set_acceptable_keys(self.acceptable_keys)

        if branch.name is None:
            header = branch.user_url
        else:
            header = branch.name
        self.ui.treeWidget.setHeaderLabels([str(header)])

        #get our list of revisions
        revisions = []
        if self.revision is not None:
            if len(self.revision) == 1:
                revno, rev_id = self.revision[0].in_history(branch)
                revisions.append(rev_id)
            elif len(sel.revision) == 2:
                from_revno, from_revid = self.revision[0].in_history(branch)
                to_revno, to_revid = self.revision[1].in_history(branch)
                if to_revid is None:
                    to_revno = branch.revno()
                if from_revno is None or to_revno is None:
                    raise errors.BzrCommandError('Cannot verify a range of '\
                                               'non-revision-history revisions')
                for revno in range(from_revno, to_revno + 1):
                    revisions.append(branch.get_rev_id(revno))
        else:
            #all revisions by default including merges
            graph = repo.get_graph()
            revisions = []
            repo.lock_read()
            for rev_id, parents in graph.iter_ancestry(
                [branch.last_revision()]):
                if _mod_revision.is_null(rev_id):
                    continue
                if parents is None:
                    # Ignore ghosts
                    continue
                revisions.append(rev_id)
            repo.unlock()
        count, result, all_verifiable =\
                                gpg_strategy.do_verifications(revisions, repo,
                                                     QApplication.processEvents)
        if all_verifiable:
            message = QTreeWidgetItem(
                [gettext("All commits signed with verifiable keys")])
            self.ui.treeWidget.addTopLevelItem(message)
            for verbose_message in gpg_strategy.verbose_valid_message(result):
                QTreeWidgetItem(message, [verbose_message])
        else:
            valid_commit_message = QTreeWidgetItem(
                [gpg_strategy.valid_commits_message(count)])
            self.ui.treeWidget.addTopLevelItem(valid_commit_message)
            for verbose_message in gpg_strategy.verbose_valid_message(result):
                QTreeWidgetItem(valid_commit_message, [verbose_message])

            expired_key_message = QTreeWidgetItem(
                [gpg_strategy.expired_commit_message(count)])
            self.ui.treeWidget.addTopLevelItem(expired_key_message)
            for verbose_message in \
                              gpg_strategy.verbose_expired_key_message(result,
                                                                         repo):
                QTreeWidgetItem(expired_key_message, [verbose_message])

            unknown_key_message = QTreeWidgetItem(
                [gpg_strategy.unknown_key_message(count)])
            self.ui.treeWidget.addTopLevelItem(unknown_key_message)
            for verbose_message in gpg_strategy.verbose_missing_key_message(
                    result):
                QTreeWidgetItem(unknown_key_message, [verbose_message])

            commit_not_valid_message = QTreeWidgetItem(
                [gpg_strategy.commit_not_valid_message(count)])
            self.ui.treeWidget.addTopLevelItem(commit_not_valid_message)
            for verbose_message in gpg_strategy.verbose_not_valid_message(
                    result, repo):
                QTreeWidgetItem(commit_not_valid_message, [verbose_message])

            commit_not_signed_message = QTreeWidgetItem(
                [gpg_strategy.commit_not_signed_message(count)])
            self.ui.treeWidget.addTopLevelItem(commit_not_signed_message)
            for verbose_message in gpg_strategy.verbose_not_signed_message(
                    result, repo):
                QTreeWidgetItem(commit_not_signed_message, [verbose_message])
        self.throbber.hide()
Esempio n. 27
0
def send(target_branch,
         revision,
         public_branch,
         remember,
         format,
         no_bundle,
         no_patch,
         output,
         from_,
         mail_to,
         message,
         body,
         to_file,
         strict=None):
    possible_transports = []
    tree, branch = controldir.ControlDir.open_containing_tree_or_branch(
        from_, possible_transports=possible_transports)[:2]
    # we may need to write data into branch's repository to calculate
    # the data to send.
    branch.lock_write()
    try:
        if output is None:
            config_stack = branch.get_config_stack()
            if mail_to is None:
                mail_to = config_stack.get('submit_to')
            mail_client = config_stack.get('mail_client')(config_stack)
            if (not getattr(mail_client, 'supports_body', False)
                    and body is not None):
                raise errors.BzrCommandError(
                    gettext(
                        'Mail client "%s" does not support specifying body') %
                    mail_client.__class__.__name__)
        if remember and target_branch is None:
            raise errors.BzrCommandError(
                gettext('--remember requires a branch to be specified.'))
        stored_target_branch = branch.get_submit_branch()
        remembered_target_branch = None
        if target_branch is None:
            target_branch = stored_target_branch
            remembered_target_branch = "submit"
        else:
            # Remembers if asked explicitly or no previous location is set
            if remember or (remember is None and stored_target_branch is None):
                branch.set_submit_branch(target_branch)
        if target_branch is None:
            target_branch = branch.get_parent()
            remembered_target_branch = "parent"
        if target_branch is None:
            raise errors.BzrCommandError(
                gettext('No submit branch known or'
                        ' specified'))
        if remembered_target_branch is not None:
            trace.note(
                gettext('Using saved {0} location "{1}" to determine '
                        'what changes to submit.').format(
                            remembered_target_branch, target_branch))

        submit_branch = Branch.open(target_branch,
                                    possible_transports=possible_transports)
        possible_transports.append(submit_branch.bzrdir.root_transport)
        if mail_to is None or format is None:
            if mail_to is None:
                mail_to = submit_branch.get_config_stack().get(
                    'child_submit_to')
            if format is None:
                formatname = submit_branch.get_child_submit_format()
                try:
                    format = format_registry.get(formatname)
                except KeyError:
                    raise errors.BzrCommandError(
                        gettext("No such send format '%s'.") % formatname)

        stored_public_branch = branch.get_public_branch()
        if public_branch is None:
            public_branch = stored_public_branch
        # Remembers if asked explicitly or no previous location is set
        elif (remember or (remember is None and stored_public_branch is None)):
            branch.set_public_branch(public_branch)
        if no_bundle and public_branch is None:
            raise errors.BzrCommandError(
                gettext('No public branch specified or'
                        ' known'))
        base_revision_id = None
        revision_id = None
        if revision is not None:
            if len(revision) > 2:
                raise errors.BzrCommandError(
                    gettext('bzr send takes '
                            'at most two one revision identifiers'))
            revision_id = revision[-1].as_revision_id(branch)
            if len(revision) == 2:
                base_revision_id = revision[0].as_revision_id(branch)
        if revision_id is None:
            if tree is not None:
                tree.check_changed_or_out_of_date(
                    strict,
                    'send_strict',
                    more_error='Use --no-strict to force the send.',
                    more_warning='Uncommitted changes will not be sent.')
            revision_id = branch.last_revision()
        if revision_id == NULL_REVISION:
            raise errors.BzrCommandError(gettext('No revisions to submit.'))
        if format is None:
            format = format_registry.get()
        directive = format(branch, revision_id, target_branch, public_branch,
                           no_patch, no_bundle, message, base_revision_id,
                           submit_branch)
        if output is None:
            directive.compose_merge_request(mail_client, mail_to, body, branch,
                                            tree)
        else:
            if directive.multiple_output_files:
                if output == '-':
                    raise errors.BzrCommandError(
                        gettext(
                            '- not supported for '
                            'merge directives that use more than one output file.'
                        ))
                if not os.path.exists(output):
                    os.mkdir(output, 0755)
                for (filename, lines) in directive.to_files():
                    path = os.path.join(output, filename)
                    outfile = open(path, 'wb')
                    try:
                        outfile.writelines(lines)
                    finally:
                        outfile.close()
            else:
                if output == '-':
                    outfile = to_file
                else:
                    outfile = open(output, 'wb')
                try:
                    outfile.writelines(directive.to_lines())
                finally:
                    if outfile is not to_file:
                        outfile.close()
    finally:
        branch.unlock()
Esempio n. 28
0
             "but it is not valid.") % (location, ))
 except errors.FileExists, err:
     if not use_existing_dir:
         raise errors.BzrCommandError(
             gettext("Target directory %s"
                     " already exists, but does not have a .bzr"
                     " directory. Supply --use-existing-dir to push"
                     " there anyway.") % location)
     # This shouldn't occur, but if it does the FileExists error will be
     # more informative than an UnboundLocalError for br_to.
     raise
 except errors.NoSuchFile:
     if not create_prefix:
         raise errors.BzrCommandError(
             gettext("Parent directory of %s"
                     " does not exist."
                     "\nYou may supply --create-prefix to create all"
                     " leading parent directories.") % location)
     # This shouldn't occur (because create_prefix is true, so
     # create_clone_on_transport should be catching NoSuchFile and
     # creating the missing directories) but if it does the original
     # NoSuchFile error will be more informative than an
     # UnboundLocalError for br_to.
     raise
 except errors.TooManyRedirections:
     raise errors.BzrCommandError(
         gettext("Too many redirections trying "
                 "to make %s.") % location)
 push_result = PushResult()
 # TODO: Some more useful message about what was copied
 try:
Esempio n. 29
0
def _show_push_branch(br_from,
                      revision_id,
                      location,
                      to_file,
                      verbose=False,
                      overwrite=False,
                      remember=False,
                      stacked_on=None,
                      create_prefix=False,
                      use_existing_dir=False):
    """Push a branch to a location.

    :param br_from: the source branch
    :param revision_id: the revision-id to push up to
    :param location: the url of the destination
    :param to_file: the output stream
    :param verbose: if True, display more output than normal
    :param overwrite: if False, a current branch at the destination may not
        have diverged from the source, otherwise the push fails
    :param remember: if True, store the location as the push location for
        the source branch
    :param stacked_on: the url of the branch, if any, to stack on;
        if set, only the revisions not in that branch are pushed
    :param create_prefix: if True, create the necessary parent directories
        at the destination if they don't already exist
    :param use_existing_dir: if True, proceed even if the destination
        directory exists without a current .bzr directory in it
    """
    to_transport = transport.get_transport(location)
    br_to = repository_to = dir_to = None
    try:
        dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
    except errors.NotBranchError:
        pass  # Didn't find anything
    else:
        # If we can open a branch, use its direct repository, otherwise see
        # if there is a repository without a branch.
        try:
            br_to = dir_to.open_branch()
        except errors.NotBranchError:
            # Didn't find a branch, can we find a repository?
            try:
                repository_to = dir_to.find_repository()
            except errors.NoRepositoryPresent:
                pass
        else:
            # Found a branch, so we must have found a repository
            repository_to = br_to.repository

    push_result = None
    if verbose:
        old_rh = []
    if dir_to is None:
        # The destination doesn't exist; create it.
        # XXX: Refactor the create_prefix/no_create_prefix code into a
        #      common helper function

        def make_directory(transport):
            transport.mkdir('.')
            return transport

        def redirected(redirected_transport, e, redirection_notice):
            return transport.get_transport(e.get_target_url())

        try:
            to_transport = transport.do_catching_redirections(
                make_directory, to_transport, redirected)
        except errors.FileExists:
            if not use_existing_dir:
                raise errors.BzrCommandError(
                    "Target directory %s"
                    " already exists, but does not have a valid .bzr"
                    " directory. Supply --use-existing-dir to push"
                    " there anyway." % location)
        except errors.NoSuchFile:
            if not create_prefix:
                raise errors.BzrCommandError(
                    "Parent directory of %s"
                    " does not exist."
                    "\nYou may supply --create-prefix to create all"
                    " leading parent directories." % location)
            builtins._create_prefix(to_transport)
        except errors.TooManyRedirections:
            raise errors.BzrCommandError("Too many redirections trying "
                                         "to make %s." % location)

        # Now the target directory exists, but doesn't have a .bzr
        # directory. So we need to create it, along with any work to create
        # all of the dependent branches, etc.
        if stacked_on is not None:
            # This should be buried in the clone method itself. TODO.
            try:
                # if the from format is stackable, this will either work or
                # trigger NotStacked. If it's not, an error will be given to
                # the user.
                br_from.get_stacked_on_url()
            except errors.NotStacked:
                pass
            # now we need to sprout the repository,
            dir_to = br_from.bzrdir._format.initialize_on_transport(
                to_transport)
            br_from.repository._format.initialize(dir_to)
            br_to = br_from._format.initialize(dir_to)
            br_to.set_stacked_on_url(stacked_on)
            # and copy the data up.
            br_from.push(br_to)
        else:
            dir_to = br_from.bzrdir.clone_on_transport(to_transport,
                                                       revision_id=revision_id)
        br_to = dir_to.open_branch()
        # TODO: Some more useful message about what was copied
        if stacked_on is not None:
            note('Created new stacked branch referring to %s.' % stacked_on)
        else:
            note('Created new branch.')
        # We successfully created the target, remember it
        if br_from.get_push_location() is None or remember:
            br_from.set_push_location(br_to.base)
    elif repository_to is None:
        # we have a bzrdir but no branch or repository
        # XXX: Figure out what to do other than complain.
        raise errors.BzrCommandError(
            "At %s you have a valid .bzr control"
            " directory, but not a branch or repository. This is an"
            " unsupported configuration. Please move the target directory"
            " out of the way and try again." % location)
    elif br_to is None:
        # We have a repository but no branch, copy the revisions, and then
        # create a branch.
        if stacked_on is not None:
            warning("Ignoring request for a stacked branch as repository "
                    "already exists at the destination location.")
        repository_to.fetch(br_from.repository, revision_id=revision_id)
        br_to = br_from.clone(dir_to, revision_id=revision_id)
        note('Created new branch.')
        if br_from.get_push_location() is None or remember:
            br_from.set_push_location(br_to.base)
    else:  # We have a valid to branch
        if stacked_on is not None:
            warning("Ignoring request for a stacked branch as branch "
                    "already exists at the destination location.")
        # We were able to connect to the remote location, so remember it.
        # (We don't need to successfully push because of possible divergence.)
        if br_from.get_push_location() is None or remember:
            br_from.set_push_location(br_to.base)
        if verbose:
            old_rh = br_to.revision_history()
        try:
            try:
                tree_to = dir_to.open_workingtree()
            except errors.NotLocalUrl:
                warning("This transport does not update the working "
                        "tree of: %s. See 'bzr help working-trees' for "
                        "more information." % br_to.base)
                push_result = br_from.push(br_to,
                                           overwrite,
                                           stop_revision=revision_id)
            except errors.NoWorkingTree:
                push_result = br_from.push(br_to,
                                           overwrite,
                                           stop_revision=revision_id)
            else:
                tree_to.lock_write()
                try:
                    push_result = br_from.push(tree_to.branch,
                                               overwrite,
                                               stop_revision=revision_id)
                    tree_to.update()
                finally:
                    tree_to.unlock()
        except errors.DivergedBranches:
            raise errors.BzrCommandError(
                'These branches have diverged.'
                '  Try using "merge" and then "push".')
    if push_result is not None:
        push_result.report(to_file)
    elif verbose:
        new_rh = br_to.revision_history()
        if old_rh != new_rh:
            # Something changed
            from bzrlib.log import show_changed_revisions
            show_changed_revisions(br_to, old_rh, new_rh, to_file=to_file)
    else:
        # we probably did a clone rather than a push, so a message was
        # emitted above
        pass