From b9ab040b45f0a0329d76fc919b0111414fdaf035 Mon Sep 17 00:00:00 2001 From: Christian Halstrick Date: Fri, 7 May 2010 15:27:44 +0200 Subject: [PATCH] Added MERGING_RESOLVED repository state The repository state tells in which state the repo is and also which actions are currently allowed. The state MERGING is telling that a commit is not possible. But this is only true in the case of unmerged paths in the index. When we are merging but have resolved all conflicts then we are in a special state: We are still merging (means the next commit should have multiple parents) but a commit is now allowed. Since the MERGING state "canCommit()" cannot be enhanced to return true/false based on the index state (MERGING is an enum value which does not have a reference to the repository its state it is representing) I had to introduce a new state MERGING_RESOLVED. This new state will report that a commit is possible. CAUTION: there might be the chance that users of jgit previously blindly did a plain commit (with only one parent) when the RepositoryState allowed them to do so. With this change these users will now be confronted with a RepositoryState which says a commit is possible but before they can commit they'll have to check the MERGE_MESSAGE and MERGE_HEAD files and use the info from these files. Change-Id: I0a885e2fe8c85049fb23722351ab89cf2c81a431 Signed-off-by: Christian Halstrick Signed-off-by: Matthias Sohn --- .../jgit/dircache/DirCacheBasicTest.java | 20 +++++++++++++++++++ .../org/eclipse/jgit/dircache/DirCache.java | 16 +++++++++++++++ .../src/org/eclipse/jgit/lib/Repository.java | 17 +++++++++++++++- .../org/eclipse/jgit/lib/RepositoryState.java | 11 ++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index b35fc7617..f4692b168 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -186,10 +186,30 @@ public class DirCacheBasicTest extends RepositoryTestCase { for (int i = 0; i < ents.length; i++) b.add(ents[i]); b.finish(); + assertFalse(dc.hasUnmergedPaths()); assertEquals(paths.length, dc.getEntryCount()); dc.clear(); assertEquals(0, dc.getEntryCount()); + assertFalse(dc.hasUnmergedPaths()); + } + + public void testDetectUnmergedPaths() throws Exception { + final DirCache dc = DirCache.read(db); + final DirCacheEntry[] ents = new DirCacheEntry[3]; + + ents[0] = new DirCacheEntry("a", 1); + ents[0].setFileMode(FileMode.REGULAR_FILE); + ents[1] = new DirCacheEntry("a", 2); + ents[1].setFileMode(FileMode.REGULAR_FILE); + ents[2] = new DirCacheEntry("a", 3); + ents[2].setFileMode(FileMode.REGULAR_FILE); + + final DirCacheBuilder b = dc.builder(); + for (int i = 0; i < ents.length; i++) + b.add(ents[i]); + b.finish(); + assertTrue(dc.hasUnmergedPaths()); } public void testFindOnEmpty() throws Exception { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index 189787dd9..3a8abc1a7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -784,4 +784,20 @@ public class DirCache { throws UnmergedPathException, IOException { return getCacheTree(true).writeTree(sortedEntries, 0, 0, ow); } + + /** + * Tells whether this index contains unmerged paths. + * + * @return {@code true} if this index contains unmerged paths. Means: at + * least one entry is of a stage different from 0. {@code false} + * will be returned if all entries are of stage 0. + */ + public boolean hasUnmergedPaths() { + for (int i = 0; i < entryCnt; i++) { + if (sortedEntries[i].getStage() > 0) { + return true; + } + } + return false; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index e2d3da6bc..9f4bb100f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -60,6 +60,7 @@ import java.util.Set; import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.RevisionSyntaxException; @@ -1117,8 +1118,22 @@ public class Repository { return RepositoryState.REBASING_MERGE; // Both versions - if (new File(gitDir,"MERGE_HEAD").exists()) + if (new File(gitDir, "MERGE_HEAD").exists()) { + // we are merging - now check whether we have unmerged paths + try { + if (!DirCache.read(this).hasUnmergedPaths()) { + // no unmerged paths -> return the MERGING_RESOLVED state + return RepositoryState.MERGING_RESOLVED; + } + } catch (IOException e) { + // Can't decide whether unmerged paths exists. Return + // MERGING state to be on the safe side (in state MERGING + // you are not allow to do anything) + e.printStackTrace(); + } return RepositoryState.MERGING; + } + if (new File(gitDir,"BISECT_LOG").exists()) return RepositoryState.BISECTING; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryState.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryState.java index 6159839b1..901d1b516 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryState.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryState.java @@ -73,6 +73,17 @@ public enum RepositoryState { public String getDescription() { return "Conflicts"; } }, + /** + * An merge where all conflicts have been resolved. The index does not + * contain any unmerged paths. + */ + MERGING_RESOLVED { + public boolean canCheckout() { return true; } + public boolean canResetHead() { return true; } + public boolean canCommit() { return true; } + public String getDescription() { return "Merged"; } + }, + /** * An unfinished rebase or am. Must resolve, skip or abort before normal work can take place */