示例#1
0
    def run(self, location, revision=None, merge_type=None, directory="."):
        from bzrlib.branch import Branch
        from bzrlib.workingtree import WorkingTree
        from bzrlib import ui
        from bzrlib.plugins.rewrite.rebase import (
            RebaseState1,
            regenerate_default_revid,
            WorkingTreeRevisionRewriter,
            )

        from_branch = Branch.open_containing(location)[0]

        if revision is not None:
            if len(revision) == 1:
                if revision[0] is not None:
                    todo = [revision[0].as_revision_id(from_branch)]
            elif len(revision) == 2:
                from_revno, from_revid = revision[0].in_history(from_branch)
                to_revno, to_revid = revision[1].in_history(from_branch)
                if to_revid is None:
                    to_revno = from_branch.revno()
                todo = []
                for revno in range(from_revno, to_revno + 1):
                    todo.append(from_branch.get_rev_id(revno))
            else:
                raise BzrCommandError(
                    "--revision takes only one or two arguments")
        else:
            raise BzrCommandError("--revision is mandatory")

        wt = WorkingTree.open(directory)
        wt.lock_write()
        try:
            state = RebaseState1(wt)
            replayer = WorkingTreeRevisionRewriter(wt, state, merge_type=merge_type)
            pb = ui.ui_factory.nested_progress_bar()
            try:
                for revid in todo:
                    pb.update("replaying commits", todo.index(revid), len(todo))
                    wt.branch.repository.fetch(from_branch.repository, revid)
                    newrevid = regenerate_default_revid(wt.branch.repository, revid)
                    replayer(revid, newrevid, [wt.last_revision()])
            finally:
                pb.finished()
        finally:
            wt.unlock()
示例#2
0
    def run(
        self,
        upstream_location=None,
        onto=None,
        revision=None,
        merge_type=None,
        verbose=False,
        dry_run=False,
        always_rebase_merges=False,
        pending_merges=False,
        directory=".",
    ):
        from bzrlib.branch import Branch
        from bzrlib.revisionspec import RevisionSpec
        from bzrlib.workingtree import WorkingTree
        from bzrlib.plugins.rewrite.rebase import (
            generate_simple_plan,
            rebase,
            RebaseState1,
            WorkingTreeRevisionRewriter,
            regenerate_default_revid,
            rebase_todo,
        )

        if revision is not None and pending_merges:
            raise BzrCommandError(gettext("--revision and --pending-merges are mutually exclusive"))

        wt = WorkingTree.open_containing(directory)[0]
        wt.lock_write()
        try:
            state = RebaseState1(wt)
            if upstream_location is None:
                if pending_merges:
                    upstream_location = directory
                else:
                    upstream_location = wt.branch.get_parent()
                    if upstream_location is None:
                        raise BzrCommandError(gettext("No upstream branch specified."))
                    note(gettext("Rebasing on %s"), upstream_location)
            upstream = Branch.open_containing(upstream_location)[0]
            upstream_repository = upstream.repository
            upstream_revision = upstream.last_revision()
            # Abort if there already is a plan file
            if state.has_plan():
                raise BzrCommandError(
                    gettext(
                        "A rebase operation was interrupted. "
                        "Continue using 'bzr rebase-continue' or abort using 'bzr "
                        "rebase-abort'"
                    )
                )

            start_revid = None
            stop_revid = None
            if revision is not None:
                if len(revision) == 1:
                    if revision[0] is not None:
                        stop_revid = revision[0].as_revision_id(wt.branch)
                elif len(revision) == 2:
                    if revision[0] is not None:
                        start_revid = revision[0].as_revision_id(wt.branch)
                    if revision[1] is not None:
                        stop_revid = revision[1].as_revision_id(wt.branch)
                else:
                    raise BzrCommandError(gettext("--revision takes only one or two arguments"))

            if pending_merges:
                wt_parents = wt.get_parent_ids()
                if len(wt_parents) in (0, 1):
                    raise BzrCommandError(gettext("No pending merges present."))
                elif len(wt_parents) > 2:
                    raise BzrCommandError(gettext("Rebasing more than one pending merge not supported"))
                stop_revid = wt_parents[1]
                assert stop_revid is not None, "stop revid invalid"

            # Check for changes in the working tree.
            if not pending_merges and wt.basis_tree().changes_from(wt).has_changed():
                raise UncommittedChanges(wt)

            # Pull required revisions
            wt.branch.repository.fetch(upstream_repository, upstream_revision)
            if onto is None:
                onto = upstream.last_revision()
            else:
                rev_spec = RevisionSpec.from_string(onto)
                onto = rev_spec.as_revision_id(upstream)

            wt.branch.repository.fetch(upstream_repository, onto)

            if stop_revid is None:
                stop_revid = wt.branch.last_revision()
            repo_graph = wt.branch.repository.get_graph()
            our_new, onto_unique = repo_graph.find_difference(stop_revid, onto)

            if start_revid is None:
                if not onto_unique:
                    self.outf.write(gettext("No revisions to rebase.\n"))
                    return
                if not our_new:
                    self.outf.write(gettext("Base branch is descendant of current " "branch. Pulling instead.\n"))
                    if not dry_run:
                        wt.pull(upstream, onto)
                    return
            # else: include extra revisions needed to make start_revid mean
            # something.

            # Create plan
            replace_map = generate_simple_plan(
                our_new,
                start_revid,
                stop_revid,
                onto,
                repo_graph,
                lambda revid, ps: regenerate_default_revid(wt.branch.repository, revid),
                not always_rebase_merges,
            )

            if verbose or dry_run:
                todo = list(rebase_todo(wt.branch.repository, replace_map))
                note(gettext("%d revisions will be rebased:") % len(todo))
                for revid in todo:
                    note("%s" % revid)

            if not dry_run:
                # Write plan file
                state.write_plan(replace_map)

                replayer = WorkingTreeRevisionRewriter(wt, state, merge_type=merge_type)

                finish_rebase(state, wt, replace_map, replayer)
        finally:
            wt.unlock()