switch (operation) {
case ABORT:
try {
- return abort(new RebaseResult(Status.ABORTED));
+ return abort(RebaseResult.ABORTED_RESULT);
} catch (IOException ioe) {
throw new JGitInternalException(ioe.getMessage(), ioe);
}
}
if (monitor.isCancelled())
- return abort(new RebaseResult(Status.ABORTED));
+ return abort(RebaseResult.ABORTED_RESULT);
if (operation == Operation.CONTINUE)
newHead = continueRebase();
}
}
if (newHead != null) {
- // point the previous head (if any) to the new commit
String headName = readFile(rebaseDir, HEAD_NAME);
- if (headName.startsWith(Constants.R_REFS)) {
- RefUpdate rup = repo.updateRef(headName);
- rup.setNewObjectId(newHead);
- Result res = rup.forceUpdate();
- switch (res) {
- case FAST_FORWARD:
- case FORCED:
- case NO_CHANGE:
- break;
- default:
- throw new JGitInternalException("Updating HEAD failed");
- }
- rup = repo.updateRef(Constants.HEAD);
- res = rup.link(headName);
- switch (res) {
- case FAST_FORWARD:
- case FORCED:
- case NO_CHANGE:
- break;
- default:
- throw new JGitInternalException("Updating HEAD failed");
- }
- }
+ updateHead(headName, newHead);
FileUtils.delete(rebaseDir, FileUtils.RECURSIVE);
if (lastStepWasForward)
- return new RebaseResult(Status.FAST_FORWARD);
- return new RebaseResult(Status.OK);
+ return RebaseResult.FAST_FORWARD_RESULT;
+ return RebaseResult.OK_RESULT;
}
- return new RebaseResult(Status.UP_TO_DATE);
+ return RebaseResult.FAST_FORWARD_RESULT;
} catch (IOException ioe) {
throw new JGitInternalException(ioe.getMessage(), ioe);
}
}
+ private void updateHead(String headName, RevCommit newHead)
+ throws IOException {
+ // point the previous head (if any) to the new commit
+
+ if (headName.startsWith(Constants.R_REFS)) {
+ RefUpdate rup = repo.updateRef(headName);
+ rup.setNewObjectId(newHead);
+ Result res = rup.forceUpdate();
+ switch (res) {
+ case FAST_FORWARD:
+ case FORCED:
+ case NO_CHANGE:
+ break;
+ default:
+ throw new JGitInternalException("Updating HEAD failed");
+ }
+ rup = repo.updateRef(Constants.HEAD);
+ res = rup.link(headName);
+ switch (res) {
+ case FAST_FORWARD:
+ case FORCED:
+ case NO_CHANGE:
+ break;
+ default:
+ throw new JGitInternalException("Updating HEAD failed");
+ }
+ }
+ }
+
private RevCommit checkoutCurrentHead() throws IOException,
NoHeadException, JGitInternalException {
ObjectId headTree = repo.resolve(Constants.HEAD + "^{tree}");
// we need to store everything into files so that we can implement
// --skip, --continue, and --abort
- // first of all, we determine the commits to be applied
- List<RevCommit> cherryPickList = new ArrayList<RevCommit>();
-
Ref head = repo.getRef(Constants.HEAD);
if (head == null || head.getObjectId() == null)
throw new RefNotFoundException(MessageFormat.format(
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, Constants.HEAD));
RevCommit headCommit = walk.lookupCommit(headId);
+ RevCommit upstream = walk.lookupCommit(upstreamCommit.getId());
+
+ if (walk.isMergedInto(upstream, headCommit))
+ return RebaseResult.UP_TO_DATE_RESULT;
+ else if (walk.isMergedInto(headCommit, upstream)) {
+ // head is already merged into upstream, fast-foward
+ monitor.beginTask(MessageFormat.format(
+ JGitText.get().resettingHead,
+ upstreamCommit.getShortMessage()), ProgressMonitor.UNKNOWN);
+ checkoutCommit(upstreamCommit);
+ monitor.endTask();
+
+ updateHead(headName, upstreamCommit);
+ return RebaseResult.FAST_FORWARD_RESULT;
+ }
+
monitor.beginTask(JGitText.get().obtainingCommitsForCherryPick,
ProgressMonitor.UNKNOWN);
+ // determine the commits to be applied
LogCommand cmd = new Git(repo).log().addRange(upstreamCommit,
headCommit);
Iterable<RevCommit> commitsToUse = cmd.call();
+
+ List<RevCommit> cherryPickList = new ArrayList<RevCommit>();
for (RevCommit commit : commitsToUse) {
+ if (commit.getParentCount() != 1)
+ throw new JGitInternalException(
+ JGitText.get().canOnlyCherryPickCommitsWithOneParent);
cherryPickList.add(commit);
}
- // if the upstream commit is in a direct line to the current head,
- // the log command will not report any commits; in this case,
- // we create the cherry-pick list ourselves
- if (cherryPickList.isEmpty()) {
- Iterable<RevCommit> parents = new Git(repo).log().add(
- upstreamCommit).call();
- for (RevCommit parent : parents) {
- if (parent.equals(headCommit))
- break;
- if (parent.getParentCount() != 1)
- throw new JGitInternalException(
- JGitText.get().canOnlyCherryPickCommitsWithOneParent);
- cherryPickList.add(parent);
- }
- }
-
- // nothing to do: return with UP_TO_DATE_RESULT
- if (cherryPickList.isEmpty())
- return RebaseResult.UP_TO_DATE_RESULT;
-
Collections.reverse(cherryPickList);
// create the folder for the meta information
FileUtils.mkdir(rebaseDir);
}
monitor.endTask();
+
// we rewind to the upstream commit
monitor.beginTask(MessageFormat.format(JGitText.get().rewinding,
upstreamCommit.getShortMessage()), ProgressMonitor.UNKNOWN);
checkoutCommit(upstreamCommit);
monitor.endTask();
+
return null;
}