/// <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); } }