Interactive Rebase: Do actions if there were conflicts
If a commit was marked for edit, reword, squash or fixup, but the interactive rebase stopped because of a conflict, the step was not done after conflict resolution. This is done now. Change-Id: If8e7ccc50469165744f2b8a53d180f9ba0f72330 Signed-off-by: Stefan Lay <stefan.lay@sap.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
18069ffe8c
commit
979e346711
|
@ -2327,6 +2327,213 @@ public String modifyCommitMessage(String commit) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRebaseShouldStopForEditInCaseOfConflict()
|
||||||
|
throws Exception {
|
||||||
|
// create file1 on master
|
||||||
|
writeTrashFile(FILE1, FILE1);
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Add file1\nnew line").call();
|
||||||
|
assertTrue(new File(db.getWorkTree(), FILE1).exists());
|
||||||
|
|
||||||
|
//change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "a");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
//change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "b");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
RebaseResult result = git.rebase().setUpstream("HEAD~2")
|
||||||
|
.runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.remove(0);
|
||||||
|
steps.get(0).setAction(Action.EDIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
}).call();
|
||||||
|
assertEquals(Status.STOPPED, result.getStatus());
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
result = git.rebase().setOperation(Operation.CONTINUE).call();
|
||||||
|
assertEquals(Status.EDIT, result.getStatus());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRebaseShouldStopForRewordInCaseOfConflict()
|
||||||
|
throws Exception {
|
||||||
|
// create file1 on master
|
||||||
|
writeTrashFile(FILE1, FILE1);
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Add file1\nnew line").call();
|
||||||
|
assertTrue(new File(db.getWorkTree(), FILE1).exists());
|
||||||
|
|
||||||
|
// change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "a");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
// change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "b");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
RebaseResult result = git.rebase().setUpstream("HEAD~2")
|
||||||
|
.runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.remove(0);
|
||||||
|
steps.get(0).setAction(Action.REWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return "rewritten commit message";
|
||||||
|
}
|
||||||
|
}).call();
|
||||||
|
assertEquals(Status.STOPPED, result.getStatus());
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
result = git.rebase().runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.remove(0);
|
||||||
|
steps.get(0).setAction(Action.REWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return "rewritten commit message";
|
||||||
|
}
|
||||||
|
}).setOperation(Operation.CONTINUE).call();
|
||||||
|
assertEquals(Status.OK, result.getStatus());
|
||||||
|
Iterator<RevCommit> logIterator = git.log().all().call().iterator();
|
||||||
|
String actualCommitMag = logIterator.next().getShortMessage();
|
||||||
|
assertEquals("rewritten commit message", actualCommitMag);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRebaseShouldSquashInCaseOfConflict() throws Exception {
|
||||||
|
// create file1 on master
|
||||||
|
writeTrashFile(FILE1, FILE1);
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Add file1\nnew line").call();
|
||||||
|
assertTrue(new File(db.getWorkTree(), FILE1).exists());
|
||||||
|
|
||||||
|
// change file2
|
||||||
|
writeTrashFile("file2", "file2");
|
||||||
|
git.add().addFilepattern("file2").call();
|
||||||
|
git.commit().setMessage("Change file2").call();
|
||||||
|
|
||||||
|
// change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "a");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
// change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "b");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
RebaseResult result = git.rebase().setUpstream("HEAD~3")
|
||||||
|
.runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.get(0).setAction(Action.PICK);
|
||||||
|
steps.remove(1);
|
||||||
|
steps.get(1).setAction(Action.SQUASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return "squashed message";
|
||||||
|
}
|
||||||
|
}).call();
|
||||||
|
assertEquals(Status.STOPPED, result.getStatus());
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
result = git.rebase().runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.get(0).setAction(Action.PICK);
|
||||||
|
steps.remove(1);
|
||||||
|
steps.get(1).setAction(Action.SQUASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return "squashed message";
|
||||||
|
}
|
||||||
|
}).setOperation(Operation.CONTINUE).call();
|
||||||
|
assertEquals(Status.OK, result.getStatus());
|
||||||
|
Iterator<RevCommit> logIterator = git.log().all().call().iterator();
|
||||||
|
String actualCommitMag = logIterator.next().getShortMessage();
|
||||||
|
assertEquals("squashed message", actualCommitMag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRebaseShouldFixupInCaseOfConflict() throws Exception {
|
||||||
|
// create file1 on master
|
||||||
|
writeTrashFile(FILE1, FILE1);
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Add file1").call();
|
||||||
|
assertTrue(new File(db.getWorkTree(), FILE1).exists());
|
||||||
|
|
||||||
|
// change file2
|
||||||
|
writeTrashFile("file2", "file2");
|
||||||
|
git.add().addFilepattern("file2").call();
|
||||||
|
git.commit().setMessage("Change file2").call();
|
||||||
|
|
||||||
|
// change file1
|
||||||
|
writeTrashFile(FILE1, FILE1 + "a");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.commit().setMessage("Change file1").call();
|
||||||
|
|
||||||
|
// change file1, add file3
|
||||||
|
writeTrashFile(FILE1, FILE1 + "b");
|
||||||
|
writeTrashFile("file3", "file3");
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
git.add().addFilepattern("file3").call();
|
||||||
|
git.commit().setMessage("Change file1, add file3").call();
|
||||||
|
|
||||||
|
RebaseResult result = git.rebase().setUpstream("HEAD~3")
|
||||||
|
.runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.get(0).setAction(Action.PICK);
|
||||||
|
steps.remove(1);
|
||||||
|
steps.get(1).setAction(Action.FIXUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
}).call();
|
||||||
|
assertEquals(Status.STOPPED, result.getStatus());
|
||||||
|
git.add().addFilepattern(FILE1).call();
|
||||||
|
result = git.rebase().runInteractively(new InteractiveHandler() {
|
||||||
|
|
||||||
|
public void prepareSteps(List<RebaseTodoLine> steps) {
|
||||||
|
steps.get(0).setAction(Action.PICK);
|
||||||
|
steps.remove(1);
|
||||||
|
steps.get(1).setAction(Action.FIXUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modifyCommitMessage(String commit) {
|
||||||
|
return "commit";
|
||||||
|
}
|
||||||
|
}).setOperation(Operation.CONTINUE).call();
|
||||||
|
assertEquals(Status.OK, result.getStatus());
|
||||||
|
Iterator<RevCommit> logIterator = git.log().all().call().iterator();
|
||||||
|
String actualCommitMsg = logIterator.next().getShortMessage();
|
||||||
|
assertEquals("Change file2", actualCommitMsg);
|
||||||
|
actualCommitMsg = logIterator.next().getShortMessage();
|
||||||
|
assertEquals("Add file1", actualCommitMsg);
|
||||||
|
assertTrue(new File(db.getWorkTree(), "file3").exists());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private File getTodoFile() {
|
private File getTodoFile() {
|
||||||
File todoFile = new File(db.getDirectory(), GIT_REBASE_TODO);
|
File todoFile = new File(db.getDirectory(), GIT_REBASE_TODO);
|
||||||
return todoFile;
|
return todoFile;
|
||||||
|
|
|
@ -61,11 +61,13 @@
|
||||||
import org.eclipse.jgit.api.RebaseResult.Status;
|
import org.eclipse.jgit.api.RebaseResult.Status;
|
||||||
import org.eclipse.jgit.api.ResetCommand.ResetType;
|
import org.eclipse.jgit.api.ResetCommand.ResetType;
|
||||||
import org.eclipse.jgit.api.errors.CheckoutConflictException;
|
import org.eclipse.jgit.api.errors.CheckoutConflictException;
|
||||||
|
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.eclipse.jgit.api.errors.InvalidRebaseStepException;
|
import org.eclipse.jgit.api.errors.InvalidRebaseStepException;
|
||||||
import org.eclipse.jgit.api.errors.InvalidRefNameException;
|
import org.eclipse.jgit.api.errors.InvalidRefNameException;
|
||||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||||
import org.eclipse.jgit.api.errors.NoHeadException;
|
import org.eclipse.jgit.api.errors.NoHeadException;
|
||||||
|
import org.eclipse.jgit.api.errors.NoMessageException;
|
||||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
|
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
|
||||||
import org.eclipse.jgit.api.errors.RefNotFoundException;
|
import org.eclipse.jgit.api.errors.RefNotFoundException;
|
||||||
import org.eclipse.jgit.api.errors.UnmergedPathsException;
|
import org.eclipse.jgit.api.errors.UnmergedPathsException;
|
||||||
|
@ -75,6 +77,7 @@
|
||||||
import org.eclipse.jgit.dircache.DirCacheCheckout;
|
import org.eclipse.jgit.dircache.DirCacheCheckout;
|
||||||
import org.eclipse.jgit.dircache.DirCacheIterator;
|
import org.eclipse.jgit.dircache.DirCacheIterator;
|
||||||
import org.eclipse.jgit.internal.JGitText;
|
import org.eclipse.jgit.internal.JGitText;
|
||||||
|
import org.eclipse.jgit.lib.AbbreviatedObjectId;
|
||||||
import org.eclipse.jgit.lib.AnyObjectId;
|
import org.eclipse.jgit.lib.AnyObjectId;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||||
|
@ -197,6 +200,10 @@ public enum Operation {
|
||||||
|
|
||||||
private boolean stopAfterInitialization = false;
|
private boolean stopAfterInitialization = false;
|
||||||
|
|
||||||
|
private RevCommit newHead;
|
||||||
|
|
||||||
|
private boolean lastStepWasForward;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param repo
|
* @param repo
|
||||||
*/
|
*/
|
||||||
|
@ -220,8 +227,8 @@ protected RebaseCommand(Repository repo) {
|
||||||
*/
|
*/
|
||||||
public RebaseResult call() throws GitAPIException, NoHeadException,
|
public RebaseResult call() throws GitAPIException, NoHeadException,
|
||||||
RefNotFoundException, WrongRepositoryStateException {
|
RefNotFoundException, WrongRepositoryStateException {
|
||||||
RevCommit newHead = null;
|
newHead = null;
|
||||||
boolean lastStepWasForward = false;
|
lastStepWasForward = false;
|
||||||
checkCallable();
|
checkCallable();
|
||||||
checkParameters();
|
checkParameters();
|
||||||
try {
|
try {
|
||||||
|
@ -261,7 +268,19 @@ public RebaseResult call() throws GitAPIException, NoHeadException,
|
||||||
|
|
||||||
if (operation == Operation.CONTINUE) {
|
if (operation == Operation.CONTINUE) {
|
||||||
newHead = continueRebase();
|
newHead = continueRebase();
|
||||||
|
List<RebaseTodoLine> doneLines = repo.readRebaseTodo(
|
||||||
|
rebaseState.getPath(DONE), true);
|
||||||
|
RebaseTodoLine step = doneLines.get(doneLines.size() - 1);
|
||||||
|
if (newHead != null
|
||||||
|
&& step.getAction() != Action.PICK) {
|
||||||
|
RebaseTodoLine newStep = new RebaseTodoLine(
|
||||||
|
step.getAction(),
|
||||||
|
AbbreviatedObjectId.fromObjectId(newHead),
|
||||||
|
step.getShortMessage());
|
||||||
|
RebaseResult result = processStep(newStep, false);
|
||||||
|
if (result != null)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
File amendFile = rebaseState.getFile(AMEND);
|
File amendFile = rebaseState.getFile(AMEND);
|
||||||
boolean amendExists = amendFile.exists();
|
boolean amendExists = amendFile.exists();
|
||||||
if (amendExists) {
|
if (amendExists) {
|
||||||
|
@ -280,8 +299,6 @@ public RebaseResult call() throws GitAPIException, NoHeadException,
|
||||||
if (operation == Operation.SKIP)
|
if (operation == Operation.SKIP)
|
||||||
newHead = checkoutCurrentHead();
|
newHead = checkoutCurrentHead();
|
||||||
|
|
||||||
ObjectReader or = repo.newObjectReader();
|
|
||||||
|
|
||||||
List<RebaseTodoLine> steps = repo.readRebaseTodo(
|
List<RebaseTodoLine> steps = repo.readRebaseTodo(
|
||||||
rebaseState.getPath(GIT_REBASE_TODO), false);
|
rebaseState.getPath(GIT_REBASE_TODO), false);
|
||||||
if (steps.size() == 0) {
|
if (steps.size() == 0) {
|
||||||
|
@ -296,81 +313,9 @@ public RebaseResult call() throws GitAPIException, NoHeadException,
|
||||||
for (int i = 0; i < steps.size(); i++) {
|
for (int i = 0; i < steps.size(); i++) {
|
||||||
RebaseTodoLine step = steps.get(i);
|
RebaseTodoLine step = steps.get(i);
|
||||||
popSteps(1);
|
popSteps(1);
|
||||||
if (Action.COMMENT.equals(step.getAction()))
|
RebaseResult result = processStep(step, true);
|
||||||
continue;
|
if (result != null) {
|
||||||
Collection<ObjectId> ids = or.resolve(step.getCommit());
|
return result;
|
||||||
if (ids.size() != 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, Status.STOPPED);
|
|
||||||
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
|
|
||||||
String ourCommitName = getOurCommitName();
|
|
||||||
CherryPickResult cherryPickResult = new Git(repo)
|
|
||||||
.cherryPick().include(commitToPick)
|
|
||||||
.setOurCommitName(ourCommitName)
|
|
||||||
.setReflogPrefix("rebase:").call(); //$NON-NLS-1$
|
|
||||||
switch (cherryPickResult.getStatus()) {
|
|
||||||
case FAILED:
|
|
||||||
if (operation == Operation.BEGIN)
|
|
||||||
return abort(new RebaseResult(
|
|
||||||
cherryPickResult.getFailingPaths()));
|
|
||||||
else
|
|
||||||
return stop(commitToPick, Status.STOPPED);
|
|
||||||
case CONFLICTING:
|
|
||||||
return stop(commitToPick, Status.STOPPED);
|
|
||||||
case OK:
|
|
||||||
newHead = cherryPickResult.getNewHead();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean isSquash = false;
|
|
||||||
switch (step.getAction()) {
|
|
||||||
case PICK:
|
|
||||||
continue; // continue rebase process on pick command
|
|
||||||
case REWORD:
|
|
||||||
String oldMessage = commitToPick.getFullMessage();
|
|
||||||
String newMessage = interactiveHandler
|
|
||||||
.modifyCommitMessage(oldMessage);
|
|
||||||
newHead = new Git(repo).commit().setMessage(newMessage)
|
|
||||||
.setAmend(true).call();
|
|
||||||
continue;
|
|
||||||
case EDIT:
|
|
||||||
rebaseState.createFile(AMEND, commitToPick.name());
|
|
||||||
return stop(commitToPick, Status.EDIT);
|
|
||||||
case COMMENT:
|
|
||||||
break;
|
|
||||||
case SQUASH:
|
|
||||||
isSquash = true;
|
|
||||||
//$FALL-THROUGH$
|
|
||||||
case FIXUP:
|
|
||||||
resetSoftToParent();
|
|
||||||
RebaseTodoLine nextStep = (i >= steps.size() - 1 ? null
|
|
||||||
: steps.get(i + 1));
|
|
||||||
File messageFixupFile = rebaseState.getFile(MESSAGE_FIXUP);
|
|
||||||
File messageSquashFile = rebaseState
|
|
||||||
.getFile(MESSAGE_SQUASH);
|
|
||||||
if (isSquash && messageFixupFile.exists())
|
|
||||||
messageFixupFile.delete();
|
|
||||||
newHead = doSquashFixup(isSquash, commitToPick,
|
|
||||||
nextStep, messageFixupFile, messageSquashFile);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
monitor.endTask();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return finishRebase(newHead, lastStepWasForward);
|
return finishRebase(newHead, lastStepWasForward);
|
||||||
|
@ -381,6 +326,98 @@ public RebaseResult call() throws GitAPIException, NoHeadException,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RebaseResult processStep(RebaseTodoLine step, boolean shouldPick)
|
||||||
|
throws IOException, GitAPIException {
|
||||||
|
if (Action.COMMENT.equals(step.getAction()))
|
||||||
|
return null;
|
||||||
|
ObjectReader or = repo.newObjectReader();
|
||||||
|
|
||||||
|
Collection<ObjectId> ids = or.resolve(step.getCommit());
|
||||||
|
if (ids.size() != 1)
|
||||||
|
throw new JGitInternalException(
|
||||||
|
"Could not resolve uniquely the abbreviated object ID");
|
||||||
|
RevCommit commitToPick = walk.parseCommit(ids.iterator().next());
|
||||||
|
if (shouldPick) {
|
||||||
|
if (monitor.isCancelled())
|
||||||
|
return new RebaseResult(commitToPick, Status.STOPPED);
|
||||||
|
RebaseResult result = cherryPickCommit(commitToPick);
|
||||||
|
if (result != null)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
boolean isSquash = false;
|
||||||
|
switch (step.getAction()) {
|
||||||
|
case PICK:
|
||||||
|
return null; // continue rebase process on pick command
|
||||||
|
case REWORD:
|
||||||
|
String oldMessage = commitToPick.getFullMessage();
|
||||||
|
String newMessage = interactiveHandler
|
||||||
|
.modifyCommitMessage(oldMessage);
|
||||||
|
newHead = new Git(repo).commit().setMessage(newMessage)
|
||||||
|
.setAmend(true).call();
|
||||||
|
return null;
|
||||||
|
case EDIT:
|
||||||
|
rebaseState.createFile(AMEND, commitToPick.name());
|
||||||
|
return stop(commitToPick, Status.EDIT);
|
||||||
|
case COMMENT:
|
||||||
|
break;
|
||||||
|
case SQUASH:
|
||||||
|
isSquash = true;
|
||||||
|
//$FALL-THROUGH$
|
||||||
|
case FIXUP:
|
||||||
|
resetSoftToParent();
|
||||||
|
List<RebaseTodoLine> steps = repo.readRebaseTodo(
|
||||||
|
rebaseState.getPath(GIT_REBASE_TODO), false);
|
||||||
|
RebaseTodoLine nextStep = steps.size() > 0 ? steps.get(0) : null;
|
||||||
|
File messageFixupFile = rebaseState.getFile(MESSAGE_FIXUP);
|
||||||
|
File messageSquashFile = rebaseState.getFile(MESSAGE_SQUASH);
|
||||||
|
if (isSquash && messageFixupFile.exists())
|
||||||
|
messageFixupFile.delete();
|
||||||
|
newHead = doSquashFixup(isSquash, commitToPick, nextStep,
|
||||||
|
messageFixupFile, messageSquashFile);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RebaseResult cherryPickCommit(RevCommit commitToPick)
|
||||||
|
throws IOException, GitAPIException, NoMessageException,
|
||||||
|
UnmergedPathsException, ConcurrentRefUpdateException,
|
||||||
|
WrongRepositoryStateException, NoHeadException {
|
||||||
|
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
|
||||||
|
String ourCommitName = getOurCommitName();
|
||||||
|
CherryPickResult cherryPickResult = new Git(repo).cherryPick()
|
||||||
|
.include(commitToPick).setOurCommitName(ourCommitName)
|
||||||
|
.setReflogPrefix("rebase:").call(); //$NON-NLS-1$
|
||||||
|
switch (cherryPickResult.getStatus()) {
|
||||||
|
case FAILED:
|
||||||
|
if (operation == Operation.BEGIN)
|
||||||
|
return abort(new RebaseResult(
|
||||||
|
cherryPickResult.getFailingPaths()));
|
||||||
|
else
|
||||||
|
return stop(commitToPick, Status.STOPPED);
|
||||||
|
case CONFLICTING:
|
||||||
|
return stop(commitToPick, Status.STOPPED);
|
||||||
|
case OK:
|
||||||
|
newHead = cherryPickResult.getNewHead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
monitor.endTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private RebaseResult finishRebase(RevCommit newHead,
|
private RebaseResult finishRebase(RevCommit newHead,
|
||||||
boolean lastStepWasForward) throws IOException {
|
boolean lastStepWasForward) throws IOException {
|
||||||
String headName = rebaseState.readFile(HEAD_NAME);
|
String headName = rebaseState.readFile(HEAD_NAME);
|
||||||
|
|
Loading…
Reference in New Issue