Ejemplo n.º 1
0
        /// <summary>
        /// Executes the
        /// <code>Rebase</code>
        /// command with all the options and parameters
        /// collected by the setter methods of this class. Each instance of this
        /// class should only be used for one invocation of the command. Don't call
        /// this method twice on an instance.
        /// </summary>
        /// <returns>an object describing the result of this command</returns>
        /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override RebaseResult Call()
        {
            RevCommit newHead            = null;
            bool      lastStepWasForward = false;

            CheckCallable();
            CheckParameters();
            try
            {
                switch (operation)
                {
                case RebaseCommand.Operation.ABORT:
                {
                    try
                    {
                        return(Abort(RebaseResult.ABORTED_RESULT));
                    }
                    catch (IOException ioe)
                    {
                        throw new JGitInternalException(ioe.Message, ioe);
                    }
                    goto case RebaseCommand.Operation.SKIP;
                }

                case RebaseCommand.Operation.SKIP:
                case RebaseCommand.Operation.CONTINUE:
                {
                    // fall through
                    string upstreamCommitName = ReadFile(rebaseDir, ONTO);
                    this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitName));
                    break;
                }

                case RebaseCommand.Operation.BEGIN:
                {
                    RebaseResult res = InitFilesAndRewind();
                    if (res != null)
                    {
                        return(res);
                    }
                    break;
                }
                }
                if (monitor.IsCancelled())
                {
                    return(Abort(RebaseResult.ABORTED_RESULT));
                }
                if (operation == RebaseCommand.Operation.CONTINUE)
                {
                    newHead = ContinueRebase();
                }
                if (operation == RebaseCommand.Operation.SKIP)
                {
                    newHead = CheckoutCurrentHead();
                }
                ObjectReader or = repo.NewObjectReader();
                IList <RebaseCommand.Step> steps = LoadSteps();
                foreach (RebaseCommand.Step step in steps)
                {
                    PopSteps(1);
                    ICollection <ObjectId> ids = or.Resolve(step.commit);
                    if (ids.Count != 1)
                    {
                        throw new JGitInternalException("Could not resolve uniquely the abbreviated object ID"
                                                        );
                    }
                    RevCommit commitToPick = walk.ParseCommit(ids.Iterator().Next());
                    if (monitor.IsCancelled())
                    {
                        return(new RebaseResult(commitToPick));
                    }
                    try
                    {
                        monitor.BeginTask(MessageFormat.Format(JGitText.Get().applyingCommit, commitToPick
                                                               .GetShortMessage()), ProgressMonitor.UNKNOWN);
                        // if the first parent of commitToPick is the current HEAD,
                        // we do a fast-forward instead of cherry-pick to avoid
                        // unnecessary object rewriting
                        newHead            = TryFastForward(commitToPick);
                        lastStepWasForward = newHead != null;
                        if (!lastStepWasForward)
                        {
                            // TODO if the content of this commit is already merged
                            // here we should skip this step in order to avoid
                            // confusing pseudo-changed
                            CherryPickResult cherryPickResult = new Git(repo).CherryPick().Include(commitToPick
                                                                                                   ).Call();
                            switch (cherryPickResult.GetStatus())
                            {
                            case CherryPickResult.CherryPickStatus.FAILED:
                            {
                                if (operation == RebaseCommand.Operation.BEGIN)
                                {
                                    return(Abort(new RebaseResult(cherryPickResult.GetFailingPaths())));
                                }
                                else
                                {
                                    return(Stop(commitToPick));
                                }
                                goto case CherryPickResult.CherryPickStatus.CONFLICTING;
                            }

                            case CherryPickResult.CherryPickStatus.CONFLICTING:
                            {
                                return(Stop(commitToPick));
                            }

                            case CherryPickResult.CherryPickStatus.OK:
                            {
                                newHead = cherryPickResult.GetNewHead();
                                break;
                            }
                            }
                        }
                    }
                    finally
                    {
                        monitor.EndTask();
                    }
                }
                if (newHead != null)
                {
                    string headName = ReadFile(rebaseDir, HEAD_NAME);
                    UpdateHead(headName, newHead);
                    FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE);
                    if (lastStepWasForward)
                    {
                        return(RebaseResult.FAST_FORWARD_RESULT);
                    }
                    return(RebaseResult.OK_RESULT);
                }
                return(RebaseResult.FAST_FORWARD_RESULT);
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
        }