Test was added which reproduce the ClassCastException when ours or theirs merge strategy is set to MergeCommand. Merger and MergeCommand were updated in order to avoid exception. Change-Id: I4c1284b4e80d82638d0677a05e5d38182526d196 Signed-off-by: Denys Digtiar <duemir@gmail.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>tags/v1.1.0.201109011030-rc2
@@ -38,9 +38,11 @@ Import-Package: org.eclipse.jgit;version="[1.1.0,1.2.0)", | |||
org.eclipse.jgit.treewalk.filter;version="[1.1.0,1.2.0)", | |||
org.eclipse.jgit.util;version="[1.1.0,1.2.0)", | |||
org.eclipse.jgit.util.io;version="[1.1.0,1.2.0)", | |||
org.junit;version="[4.0.0,5.0.0)", | |||
org.hamcrest.core;version="[1.1.0,2.0.0)", | |||
org.hamcrest;version="[1.1.0,2.0.0)" | |||
org.hamcrest;version="[1.1.0,2.0.0)", | |||
org.junit;version="[4.4.0,5.0.0)", | |||
org.junit.runner;version="[4.4.0,5.0.0)", | |||
org.junit.experimental.theories;version="[4.4.0,5.0.0)" | |||
Require-Bundle: com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)" | |||
Export-Package: org.eclipse.jgit.lib | |||
@@ -62,8 +62,17 @@ import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.util.FileUtils; | |||
import org.junit.Test; | |||
import org.junit.experimental.theories.DataPoints; | |||
import org.junit.experimental.theories.Theories; | |||
import org.junit.experimental.theories.Theory; | |||
import org.junit.runner.RunWith; | |||
@RunWith(Theories.class) | |||
public class MergeCommandTest extends RepositoryTestCase { | |||
public static @DataPoints | |||
MergeStrategy[] mergeStrategies = MergeStrategy.get(); | |||
@Test | |||
public void testMergeInItself() throws Exception { | |||
Git git = new Git(db); | |||
@@ -161,6 +170,28 @@ public class MergeCommandTest extends RepositoryTestCase { | |||
} | |||
} | |||
@Theory | |||
public void testMergeSuccessAllStrategies(MergeStrategy mergeStrategy) | |||
throws Exception { | |||
Git git = new Git(db); | |||
RevCommit first = git.commit().setMessage("first").call(); | |||
createBranch(first, "refs/heads/side"); | |||
writeTrashFile("a", "a"); | |||
git.add().addFilepattern("a").call(); | |||
git.commit().setMessage("second").call(); | |||
checkoutBranch("refs/heads/side"); | |||
writeTrashFile("b", "b"); | |||
git.add().addFilepattern("b").call(); | |||
git.commit().setMessage("third").call(); | |||
MergeResult result = git.merge().setStrategy(mergeStrategy) | |||
.include(db.getRef(Constants.MASTER)).call(); | |||
assertEquals(MergeStatus.MERGED, result.getMergeStatus()); | |||
} | |||
@Test | |||
public void testContentMerge() throws Exception { | |||
Git git = new Git(db); |
@@ -71,9 +71,9 @@ import org.eclipse.jgit.lib.RefUpdate.Result; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.merge.MergeMessageFormatter; | |||
import org.eclipse.jgit.merge.MergeStrategy; | |||
import org.eclipse.jgit.merge.Merger; | |||
import org.eclipse.jgit.merge.ResolveMerger; | |||
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; | |||
import org.eclipse.jgit.merge.ThreeWayMerger; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.eclipse.jgit.treewalk.FileTreeIterator; | |||
@@ -193,8 +193,7 @@ public class MergeCommand extends GitCommand<MergeResult> { | |||
commits, head); | |||
repo.writeMergeCommitMsg(mergeMessage); | |||
repo.writeMergeHeads(Arrays.asList(ref.getObjectId())); | |||
ThreeWayMerger merger = (ThreeWayMerger) mergeStrategy | |||
.newMerger(repo); | |||
Merger merger = mergeStrategy.newMerger(repo); | |||
boolean noProblems; | |||
Map<String, org.eclipse.jgit.merge.MergeResult<?>> lowLevelResults = null; | |||
Map<String, MergeFailureReason> failingPaths = null; |
@@ -134,7 +134,7 @@ public abstract class Merger { | |||
* one or more sources could not be read, or outputs could not | |||
* be written to the Repository. | |||
*/ | |||
public boolean merge(final AnyObjectId[] tips) throws IOException { | |||
public boolean merge(final AnyObjectId... tips) throws IOException { | |||
sourceObjects = new RevObject[tips.length]; | |||
for (int i = 0; i < tips.length; i++) | |||
sourceObjects[i] = walk.parseAny(tips[i]); |
@@ -84,7 +84,7 @@ public abstract class ThreeWayMerger extends Merger { | |||
* @param id | |||
* common base treeish; null to automatically compute the common | |||
* base from the input commits during | |||
* {@link #merge(AnyObjectId, AnyObjectId)}. | |||
* {@link #merge(AnyObjectId...)}. | |||
* @throws IncorrectObjectTypeException | |||
* the object is not a treeish. | |||
* @throws MissingObjectException | |||
@@ -101,33 +101,8 @@ public abstract class ThreeWayMerger extends Merger { | |||
} | |||
} | |||
/** | |||
* Merge together two tree-ish objects. | |||
* <p> | |||
* Any tree-ish may be supplied as inputs. Commits and/or tags pointing at | |||
* trees or commits may be passed as input objects. | |||
* | |||
* @param a | |||
* source tree to be combined together. | |||
* @param b | |||
* source tree to be combined together. | |||
* @return true if the merge was completed without conflicts; false if the | |||
* merge strategy cannot handle this merge or there were conflicts | |||
* preventing it from automatically resolving all paths. | |||
* @throws IncorrectObjectTypeException | |||
* one of the input objects is not a commit, but the strategy | |||
* requires it to be a commit. | |||
* @throws IOException | |||
* one or more sources could not be read, or outputs could not | |||
* be written to the Repository. | |||
*/ | |||
public boolean merge(final AnyObjectId a, final AnyObjectId b) | |||
throws IOException { | |||
return merge(new AnyObjectId[] { a, b }); | |||
} | |||
@Override | |||
public boolean merge(final AnyObjectId[] tips) throws IOException { | |||
public boolean merge(final AnyObjectId... tips) throws IOException { | |||
if (tips.length != 2) | |||
return false; | |||
return super.merge(tips); |
@@ -55,7 +55,6 @@ import org.eclipse.jgit.lib.ObjectReader; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.merge.MergeStrategy; | |||
import org.eclipse.jgit.merge.Merger; | |||
import org.eclipse.jgit.merge.ThreeWayMergeStrategy; | |||
import org.eclipse.jgit.merge.ThreeWayMerger; | |||
import org.eclipse.jgit.treewalk.AbstractTreeIterator; | |||
import org.eclipse.jgit.treewalk.TreeWalk; | |||
@@ -323,23 +322,13 @@ public class NoteMapMerger { | |||
ObjectId theirsId = write(theirsList); | |||
inserter.flush(); | |||
ObjectId resultTreeId; | |||
if (nonNotesMergeStrategy instanceof ThreeWayMergeStrategy) { | |||
ThreeWayMerger m = ((ThreeWayMergeStrategy) nonNotesMergeStrategy) | |||
.newMerger(db, true); | |||
m.setBase(baseId); | |||
if (!m.merge(oursId, theirsId)) | |||
throw new NotesMergeConflictException(baseList, oursList, | |||
theirsList); | |||
resultTreeId = m.getResultTreeId(); | |||
} else { | |||
Merger m = nonNotesMergeStrategy.newMerger(db, true); | |||
if (!m.merge(new AnyObjectId[] { oursId, theirsId })) | |||
throw new NotesMergeConflictException(baseList, oursList, | |||
theirsList); | |||
resultTreeId = m.getResultTreeId(); | |||
} | |||
Merger m = nonNotesMergeStrategy.newMerger(db, true); | |||
if (m instanceof ThreeWayMerger) | |||
((ThreeWayMerger) m).setBase(baseId); | |||
if (!m.merge(oursId, theirsId)) | |||
throw new NotesMergeConflictException(baseList, oursList, | |||
theirsList); | |||
ObjectId resultTreeId = m.getResultTreeId(); | |||
AbbreviatedObjectId none = AbbreviatedObjectId.fromString(""); | |||
return NoteParser.parse(none, resultTreeId, reader).nonNotes; | |||
} |