Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java158
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java4
2 files changed, 162 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
index 987e64731e..2761989c71 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
@@ -638,6 +638,164 @@ public class MergeCommandTest extends RepositoryTestCase {
assertEquals(RepositoryState.MERGING, db.getRepositoryState());
}
+ @Test
+ public void testSuccessfulMergeFailsDueToDirtyIndex() throws Exception {
+ Git git = new Git(db);
+
+ File fileA = writeTrashFile("a", "a");
+ RevCommit initialCommit = addAllAndCommit(git);
+
+ // switch branch
+ createBranch(initialCommit, "refs/heads/side");
+ checkoutBranch("refs/heads/side");
+ // modify file a
+ write(fileA, "a(side)");
+ writeTrashFile("b", "b");
+ RevCommit sideCommit = addAllAndCommit(git);
+
+ // switch branch
+ checkoutBranch("refs/heads/master");
+ writeTrashFile("c", "c");
+ addAllAndCommit(git);
+
+ // modify and add file a
+ write(fileA, "a(modified)");
+ git.add().addFilepattern("a").call();
+ // do not commit
+
+ // get current index state
+ String indexState = indexState(CONTENT);
+
+ // merge
+ MergeResult result = git.merge().include(sideCommit.getId())
+ .setStrategy(MergeStrategy.RESOLVE).call();
+
+ checkMergeFailedResult(result, indexState, fileA);
+ }
+
+ @Test
+ public void testConflictingMergeFailsDueToDirtyIndex() throws Exception {
+ Git git = new Git(db);
+
+ File fileA = writeTrashFile("a", "a");
+ RevCommit initialCommit = addAllAndCommit(git);
+
+ // switch branch
+ createBranch(initialCommit, "refs/heads/side");
+ checkoutBranch("refs/heads/side");
+ // modify file a
+ write(fileA, "a(side)");
+ writeTrashFile("b", "b");
+ RevCommit sideCommit = addAllAndCommit(git);
+
+ // switch branch
+ checkoutBranch("refs/heads/master");
+ // modify file a - this will cause a conflict during merge
+ write(fileA, "a(master)");
+ writeTrashFile("c", "c");
+ addAllAndCommit(git);
+
+ // modify and add file a
+ write(fileA, "a(modified)");
+ git.add().addFilepattern("a").call();
+ // do not commit
+
+ // get current index state
+ String indexState = indexState(CONTENT);
+
+ // merge
+ MergeResult result = git.merge().include(sideCommit.getId())
+ .setStrategy(MergeStrategy.RESOLVE).call();
+
+ checkMergeFailedResult(result, indexState, fileA);
+ }
+
+ @Test
+ public void testSuccessfulMergeFailsDueToDirtyWorktree() throws Exception {
+ Git git = new Git(db);
+
+ File fileA = writeTrashFile("a", "a");
+ RevCommit initialCommit = addAllAndCommit(git);
+
+ // switch branch
+ createBranch(initialCommit, "refs/heads/side");
+ checkoutBranch("refs/heads/side");
+ // modify file a
+ write(fileA, "a(side)");
+ writeTrashFile("b", "b");
+ RevCommit sideCommit = addAllAndCommit(git);
+
+ // switch branch
+ checkoutBranch("refs/heads/master");
+ writeTrashFile("c", "c");
+ addAllAndCommit(git);
+
+ // modify file a
+ write(fileA, "a(modified)");
+ // do not add and commit
+
+ // get current index state
+ String indexState = indexState(CONTENT);
+
+ // merge
+ MergeResult result = git.merge().include(sideCommit.getId())
+ .setStrategy(MergeStrategy.RESOLVE).call();
+
+ checkMergeFailedResult(result, indexState, fileA);
+ }
+
+ @Test
+ public void testConflictingMergeFailsDueToDirtyWorktree() throws Exception {
+ Git git = new Git(db);
+
+ File fileA = writeTrashFile("a", "a");
+ RevCommit initialCommit = addAllAndCommit(git);
+
+ // switch branch
+ createBranch(initialCommit, "refs/heads/side");
+ checkoutBranch("refs/heads/side");
+ // modify file a
+ write(fileA, "a(side)");
+ writeTrashFile("b", "b");
+ RevCommit sideCommit = addAllAndCommit(git);
+
+ // switch branch
+ checkoutBranch("refs/heads/master");
+ // modify file a - this will cause a conflict during merge
+ write(fileA, "a(master)");
+ writeTrashFile("c", "c");
+ addAllAndCommit(git);
+
+ // modify file a
+ write(fileA, "a(modified)");
+ // do not add and commit
+
+ // get current index state
+ String indexState = indexState(CONTENT);
+
+ // merge
+ MergeResult result = git.merge().include(sideCommit.getId())
+ .setStrategy(MergeStrategy.RESOLVE).call();
+
+ checkMergeFailedResult(result, indexState, fileA);
+ }
+
+ private RevCommit addAllAndCommit(final Git git) throws Exception {
+ git.add().addFilepattern(".").call();
+ return git.commit().setMessage("message").call();
+ }
+
+ private void checkMergeFailedResult(final MergeResult result,
+ final String indexState, final File fileA) throws Exception {
+ assertEquals(MergeStatus.FAILED, result.getMergeStatus());
+ assertEquals("a(modified)", read(fileA));
+ assertFalse(new File(db.getWorkTree(), "b").exists());
+ assertEquals("c", read(new File(db.getWorkTree(), "c")));
+ assertEquals(indexState, indexState(CONTENT));
+ assertEquals(null, result.getConflicts());
+ assertEquals(RepositoryState.SAFE, db.getRepositoryState());
+ }
+
private void createBranch(ObjectId objectId, String branchName) throws IOException {
RefUpdate updateRef = db.updateRef(branchName);
updateRef.setNewObjectId(objectId);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index a055131d61..5e99fc00f1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -393,6 +393,10 @@ public class ResolveMerger extends ThreeWayMerger {
if (modeB == modeO && tw.idEqual(T_BASE, T_OURS)) {
// OURS was not changed compared to BASE. All changes must be in
// THEIRS. THEIRS is chosen.
+
+ // Check worktree before checking out THEIRS
+ if (isWorktreeDirty())
+ return false;
if (nonTree(modeT)) {
DirCacheEntry e = add(tw.getRawPath(), theirs,
DirCacheEntry.STAGE_0);

Back to the top