From dcf7bd9a8f7acafbd1461dc0414aded2db030983 Mon Sep 17 00:00:00 2001 From: Philipp Thun Date: Mon, 21 Mar 2011 12:33:58 +0100 Subject: [PATCH] Improve MergeResult Add paths causing abnormal merge failures (e.g. due to unstaged changes) to the MergeResult returned by MergeCommand. This helps callers to better handle (e.g. present) merge results. Change-Id: Idb8cf04c5cecfb6a12cb880e16febfc3b9358564 Signed-off-by: Philipp Thun --- .../eclipse/jgit/api/MergeCommandTest.java | 15 ++++-- .../org/eclipse/jgit/api/MergeCommand.java | 2 +- .../src/org/eclipse/jgit/api/MergeResult.java | 53 ++++++++++++++++++- .../org/eclipse/jgit/merge/ResolveMerger.java | 11 ++++ 4 files changed, 74 insertions(+), 7 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 132aaa1ac..94f0906a3 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 @@ -57,6 +57,7 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.merge.MergeStrategy; +import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Test; @@ -664,7 +665,8 @@ public class MergeCommandTest extends RepositoryTestCase { MergeResult result = git.merge().include(sideCommit.getId()) .setStrategy(MergeStrategy.RESOLVE).call(); - checkMergeFailedResult(result, indexState, fileA); + checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX, + indexState, fileA); } @Test @@ -701,7 +703,8 @@ public class MergeCommandTest extends RepositoryTestCase { MergeResult result = git.merge().include(sideCommit.getId()) .setStrategy(MergeStrategy.RESOLVE).call(); - checkMergeFailedResult(result, indexState, fileA); + checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX, + indexState, fileA); } @Test @@ -735,7 +738,8 @@ public class MergeCommandTest extends RepositoryTestCase { MergeResult result = git.merge().include(sideCommit.getId()) .setStrategy(MergeStrategy.RESOLVE).call(); - checkMergeFailedResult(result, indexState, fileA); + checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE, + indexState, fileA); } @Test @@ -771,7 +775,8 @@ public class MergeCommandTest extends RepositoryTestCase { MergeResult result = git.merge().include(sideCommit.getId()) .setStrategy(MergeStrategy.RESOLVE).call(); - checkMergeFailedResult(result, indexState, fileA); + checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE, + indexState, fileA); } private RevCommit addAllAndCommit(final Git git) throws Exception { @@ -780,8 +785,10 @@ public class MergeCommandTest extends RepositoryTestCase { } private void checkMergeFailedResult(final MergeResult result, + final MergeFailureReason reason, final String indexState, final File fileA) throws Exception { assertEquals(MergeStatus.FAILED, result.getMergeStatus()); + assertEquals(reason, result.getFailingPaths().get("a")); assertEquals("a(modified)", read(fileA)); assertFalse(new File(db.getWorkTree(), "b").exists()); assertEquals("c", read(new File(db.getWorkTree(), "c"))); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java index 29ce00e44..39c079896 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java @@ -229,7 +229,7 @@ public class MergeCommand extends GitCommand { new ObjectId[] { headCommit.getId(), srcCommit.getId() }, MergeStatus.FAILED, mergeStrategy, - lowLevelResults, null); + lowLevelResults, failingPaths, null); } else return new MergeResult(null, merger.getBaseCommit(0, 1), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java index ceef6e69a..9d84c1844 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java @@ -53,6 +53,7 @@ import org.eclipse.jgit.merge.MergeChunk; import org.eclipse.jgit.merge.MergeChunk.ConflictState; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.ResolveMerger; +import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; /** * Encapsulates the result of a {@link MergeCommand}. @@ -116,6 +117,8 @@ public class MergeResult { private MergeStrategy mergeStrategy; + private Map failingPaths; + /** * @param newHead * the object the head points at after the merge @@ -127,10 +130,11 @@ public class MergeResult { * all the commits which have been merged together * @param mergeStatus * the status the merge resulted in + * @param lowLevelResults + * merge results as returned by + * {@link ResolveMerger#getMergeResults()} * @param mergeStrategy * the used {@link MergeStrategy} - * @param lowLevelResults - * merge results as returned by {@link ResolveMerger#getMergeResults()} */ public MergeResult(ObjectId newHead, ObjectId base, ObjectId[] mergedCommits, MergeStatus mergeStatus, @@ -162,12 +166,44 @@ public class MergeResult { MergeStrategy mergeStrategy, Map> lowLevelResults, String description) { + this(newHead, base, mergedCommits, mergeStatus, mergeStrategy, + lowLevelResults, null, null); + } + + /** + * @param newHead + * the object the head points at after the merge + * @param base + * the common base which was used to produce a content-merge. May + * be null if the merge-result was produced without + * computing a common base + * @param mergedCommits + * all the commits which have been merged together + * @param mergeStatus + * the status the merge resulted in + * @param mergeStrategy + * the used {@link MergeStrategy} + * @param lowLevelResults + * merge results as returned by + * {@link ResolveMerger#getMergeResults()} + * @param failingPaths + * list of paths causing this merge to fail abnormally as + * returned by {@link ResolveMerger#getFailingPaths()} + * @param description + * a user friendly description of the merge result + */ + public MergeResult(ObjectId newHead, ObjectId base, + ObjectId[] mergedCommits, MergeStatus mergeStatus, + MergeStrategy mergeStrategy, + Map> lowLevelResults, + Map failingPaths, String description) { this.newHead = newHead; this.mergedCommits = mergedCommits; this.base = base; this.mergeStatus = mergeStatus; this.mergeStrategy = mergeStrategy; this.description = description; + this.failingPaths = failingPaths; if (lowLevelResults != null) for (Map.Entry> result : lowLevelResults .entrySet()) @@ -245,6 +281,8 @@ public class MergeResult { * @param lowLevelResult */ public void addConflict(String path, org.eclipse.jgit.merge.MergeResult lowLevelResult) { + if (!lowLevelResult.containsConflicts()) + return; if (conflicts == null) conflicts = new HashMap(); int nrOfConflicts = 0; @@ -316,4 +354,15 @@ public class MergeResult { public Map getConflicts() { return conflicts; } + + /** + * Returns a list of paths causing this merge to fail abnormally as returned + * by {@link ResolveMerger#getFailingPaths()} + * + * @return the list of paths causing this merge to fail abnormally or + * null if no abnormal failure occurred + */ + public Map getFailingPaths() { + return failingPaths; + } } 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 5e99fc00f..a4c795cc5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -637,6 +637,17 @@ public class ResolveMerger extends ThreeWayMerger { return (failingPaths.size() == 0) ? null : failingPaths; } + /** + * Returns whether this merge failed abnormally (i.e. not because of a + * conflict) + * + * @return true if an abnormal failure occurred, + * false otherwise + */ + public boolean failedAbnormally() { + return failingPaths.size() > 0; + } + /** * Sets the DirCache which shall be used by this merger. If the DirCache is * not set explicitly this merger will implicitly get and lock a default