]> source.dussan.org Git - jgit.git/commitdiff
Teach NameConflictTreeWalk to report DF conflicts 69/1169/3
authorChristian Halstrick <christian.halstrick@sap.com>
Thu, 22 Jul 2010 13:57:14 +0000 (15:57 +0200)
committerChristian Halstrick <christian.halstrick@sap.com>
Wed, 28 Jul 2010 15:26:31 +0000 (17:26 +0200)
Add a method isDirectoryFileConflict() to NameConflictTreeWalk which
tells whether the current path is part of a directory/file conflict.

Change-Id: Iffcc7090aaec743dd6f3fd1a333cac96c587ae5d
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java

index 675331baf47261cc94da6d73315b818a7d7a575f..e59b7c18d3250bde5cf7484f4d7f84e9028fadc2 100644 (file)
@@ -120,11 +120,15 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
                tw.addTree(new DirCacheIterator(tree1));
 
                assertModes("a", REGULAR_FILE, TREE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
                assertTrue(tw.isSubtree());
                tw.enterSubtree();
                assertModes("a/b", MISSING, REGULAR_FILE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
                assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
+               assertFalse(tw.isDirectoryFileConflict());
                assertModes("a0b", SYMLINK, MISSING, tw);
+               assertFalse(tw.isDirectoryFileConflict());
        }
 
        public void testDF_GapByOne() throws Exception {
@@ -153,10 +157,14 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
 
                assertModes("a", REGULAR_FILE, TREE, tw);
                assertTrue(tw.isSubtree());
+               assertTrue(tw.isDirectoryFileConflict());
                tw.enterSubtree();
                assertModes("a/b", MISSING, REGULAR_FILE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
                assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw);
+               assertFalse(tw.isDirectoryFileConflict());
                assertModes("a0b", SYMLINK, MISSING, tw);
+               assertFalse(tw.isDirectoryFileConflict());
        }
 
        public void testDF_SkipsSeenSubtree() throws Exception {
@@ -185,10 +193,57 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
 
                assertModes("a", REGULAR_FILE, TREE, tw);
                assertTrue(tw.isSubtree());
+               assertTrue(tw.isDirectoryFileConflict());
                tw.enterSubtree();
                assertModes("a/b", MISSING, REGULAR_FILE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
                assertModes("a.b", MISSING, EXECUTABLE_FILE, tw);
+               assertFalse(tw.isDirectoryFileConflict());
                assertModes("a0b", SYMLINK, SYMLINK, tw);
+               assertFalse(tw.isDirectoryFileConflict());
+       }
+
+       public void testDF_DetectConflict() throws Exception {
+               final DirCache tree0 = db.readDirCache();
+               final DirCache tree1 = db.readDirCache();
+               {
+                       final DirCacheBuilder b0 = tree0.builder();
+                       final DirCacheBuilder b1 = tree1.builder();
+
+                       b0.add(makeEntry("0", REGULAR_FILE));
+                       b0.add(makeEntry("a", REGULAR_FILE));
+                       b1.add(makeEntry("0", REGULAR_FILE));
+                       b1.add(makeEntry("a.b", REGULAR_FILE));
+                       b1.add(makeEntry("a/b", REGULAR_FILE));
+                       b1.add(makeEntry("a/c/e", REGULAR_FILE));
+
+                       b0.finish();
+                       b1.finish();
+                       assertEquals(2, tree0.getEntryCount());
+                       assertEquals(4, tree1.getEntryCount());
+               }
+
+               final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
+               tw.reset();
+               tw.addTree(new DirCacheIterator(tree0));
+               tw.addTree(new DirCacheIterator(tree1));
+
+               assertModes("0", REGULAR_FILE, REGULAR_FILE, tw);
+               assertFalse(tw.isDirectoryFileConflict());
+               assertModes("a", REGULAR_FILE, TREE, tw);
+               assertTrue(tw.isSubtree());
+               assertTrue(tw.isDirectoryFileConflict());
+               tw.enterSubtree();
+               assertModes("a/b", MISSING, REGULAR_FILE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
+               assertModes("a/c", MISSING, TREE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
+               tw.enterSubtree();
+               assertModes("a/c/e", MISSING, REGULAR_FILE, tw);
+               assertTrue(tw.isDirectoryFileConflict());
+
+               assertModes("a.b", MISSING, REGULAR_FILE, tw);
+               assertFalse(tw.isDirectoryFileConflict());
        }
 
        private DirCacheEntry makeEntry(final String path, final FileMode mode)
index 99126e8615a90338c0c3a6137139dc183b9dbf1d..2d6acbddf0ffeda8486c5846e87ce730b885ae46 100644 (file)
@@ -87,6 +87,8 @@ public class NameConflictTreeWalk extends TreeWalk {
 
        private boolean fastMinHasMatch;
 
+       private AbstractTreeIterator dfConflict;
+
        /**
         * Create a new tree walker for a given repository.
         *
@@ -141,6 +143,7 @@ public class NameConflictTreeWalk extends TreeWalk {
                if (minRef.eof())
                        return minRef;
 
+               boolean hasConflict = false;
                minRef.matches = minRef;
                while (++i < trees.length) {
                        final AbstractTreeIterator t = trees[i];
@@ -156,6 +159,7 @@ public class NameConflictTreeWalk extends TreeWalk {
                                        // tree anyway.
                                        //
                                        t.matches = minRef;
+                                       hasConflict = true;
                                } else {
                                        fastMinHasMatch = false;
                                        t.matches = t;
@@ -182,10 +186,13 @@ public class NameConflictTreeWalk extends TreeWalk {
                                }
                                t.matches = t;
                                minRef = t;
+                               hasConflict = true;
                        } else
                                fastMinHasMatch = false;
                }
 
+               if (hasConflict && fastMinHasMatch && dfConflict == null)
+                       dfConflict = minRef;
                return minRef;
        }
 
@@ -281,6 +288,10 @@ public class NameConflictTreeWalk extends TreeWalk {
                        for (final AbstractTreeIterator t : trees)
                                if (t.matches == minRef)
                                        t.matches = treeMatch;
+
+                       if (dfConflict == null)
+                               dfConflict = treeMatch;
+
                        return treeMatch;
                }
 
@@ -302,6 +313,9 @@ public class NameConflictTreeWalk extends TreeWalk {
                                t.matches = null;
                        }
                }
+
+               if (ch == dfConflict)
+                       dfConflict = null;
        }
 
        @Override
@@ -319,5 +333,26 @@ public class NameConflictTreeWalk extends TreeWalk {
                                t.matches = null;
                        }
                }
+
+               if (ch == dfConflict)
+                       dfConflict = null;
+       }
+
+       /**
+        * True if the current entry is covered by a directory/file conflict.
+        *
+        * This means that for some prefix of the current entry's path, this walk
+        * has detected a directory/file conflict. Also true if the current entry
+        * itself is a directory/file conflict.
+        *
+        * Example: If this TreeWalk points to foo/bar/a.txt and this method returns
+        * true then you know that either for path foo or for path foo/bar files and
+        * folders were detected.
+        *
+        * @return <code>true</code> if the current entry is covered by a
+        *         directory/file conflict, <code>false</code> otherwise
+        */
+       public boolean isDirectoryFileConflict() {
+               return dfConflict != null;
        }
 }