Browse Source

Fix rebase > continue when nothing left to commit.

If after resolving all conflicts nothing is left to commit, return
an according result, so that downstreams (EGit, ...) can behave like
cgit, and display a nice message informing the user.

Currently, EGit displays a "HEAD advanced fast forward" message, which
is absolutely not helpful at all.

This is the basic API revamping required to get that state communicated
to the outside world (EGit).

Bug: 336812
Change-Id: If2665005cf54a5b51c0fe80bad019fa42b0205af
tags/v2.0.0.201206130900-r
Markus Duft 12 years ago
parent
commit
edc1fee033

+ 58
- 2
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java View File

@@ -502,6 +502,55 @@ public class RebaseCommandTest extends RepositoryTestCase {
.getFullMessage());
}

@Test
public void testStopOnConflictAndContinueWithNoDeltaToMaster()
throws Exception {
// create file1 on master
RevCommit firstInMaster = writeFileAndCommit(FILE1, "Add file1", "1",
"2", "3");
// change in master
writeFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3");

checkFile(FILE1, "1master", "2", "3");
// create a topic branch based on the first commit
createBranch(firstInMaster, "refs/heads/topic");
checkoutBranch("refs/heads/topic");
// we have the old content again
checkFile(FILE1, "1", "2", "3");

// change first line (conflicting)
writeFileAndCommit(FILE1,
"change file1 in topic\n\nThis is conflicting", "1topic", "2",
"3", "4topic");

RebaseResult res = git.rebase().setUpstream("refs/heads/master").call();
assertEquals(Status.STOPPED, res.getStatus());

// continue should throw a meaningful exception
try {
res = git.rebase().setOperation(Operation.CONTINUE).call();
fail("Expected Exception not thrown");
} catch (UnmergedPathsException e) {
// expected
}

// merge the file; the second topic commit should go through
writeFileAndAdd(FILE1, "1master", "2", "3");

res = git.rebase().setOperation(Operation.CONTINUE).call();
assertNotNull(res);
assertEquals(Status.NOTHING_TO_COMMIT, res.getStatus());
assertEquals(RepositoryState.REBASING_INTERACTIVE,
db.getRepositoryState());

git.rebase().setOperation(Operation.SKIP).call();

ObjectId headId = db.resolve(Constants.HEAD);
RevWalk rw = new RevWalk(db);
RevCommit rc = rw.parseCommit(headId);
assertEquals("change file1 in master", rc.getFullMessage());
}

@Test
public void testStopOnConflictAndFailContinueIfFileIsDirty()
throws Exception {
@@ -775,8 +824,15 @@ public class RebaseCommandTest extends RepositoryTestCase {

res = git.rebase().setOperation(Operation.CONTINUE).call();
assertNotNull(res);
assertEquals(Status.OK, res.getStatus());
assertEquals(RepositoryState.SAFE, db.getRepositoryState());

// nothing to commit. this leaves the repo state in rebase, so that the
// user can decide what to do. if he accidentally committed, reset soft,
// and continue, if he really has nothing to commit, skip.
assertEquals(Status.NOTHING_TO_COMMIT, res.getStatus());
assertEquals(RepositoryState.REBASING_INTERACTIVE,
db.getRepositoryState());

git.rebase().setOperation(Operation.SKIP).call();

ObjectId headId = db.resolve(Constants.HEAD);
RevWalk rw = new RevWalk(db);

+ 11
- 1
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java View File

@@ -220,9 +220,19 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
if (monitor.isCancelled())
return abort(RebaseResult.ABORTED_RESULT);

if (operation == Operation.CONTINUE)
if (operation == Operation.CONTINUE) {
newHead = continueRebase();

if (newHead == null) {
// continueRebase() returns null only if no commit was
// neccessary. This means that no changes where left over
// after resolving all conflicts. In this case, cgit stops
// and displays a nice message to the user, telling him to
// either do changes or skip the commit instead of continue.
return RebaseResult.NOTHING_TO_COMMIT_RESULT;
}
}

if (operation == Operation.SKIP)
newHead = checkoutCurrentHead();


+ 13
- 0
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java View File

@@ -109,6 +109,16 @@ public class RebaseResult {
public boolean isSuccessful() {
return true;
}
},

/**
* Continue with nothing left to commit (possibly want skip).
*/
NOTHING_TO_COMMIT {
@Override
public boolean isSuccessful() {
return false;
}
};

/**
@@ -127,6 +137,9 @@ public class RebaseResult {
static final RebaseResult FAST_FORWARD_RESULT = new RebaseResult(
Status.FAST_FORWARD);

static final RebaseResult NOTHING_TO_COMMIT_RESULT = new RebaseResult(
Status.NOTHING_TO_COMMIT);

private final Status status;

private final RevCommit currentCommit;

Loading…
Cancel
Save