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 {
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 {
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)
private boolean fastMinHasMatch;
+ private AbstractTreeIterator dfConflict;
+
/**
* Create a new tree walker for a given repository.
*
if (minRef.eof())
return minRef;
+ boolean hasConflict = false;
minRef.matches = minRef;
while (++i < trees.length) {
final AbstractTreeIterator t = trees[i];
// tree anyway.
//
t.matches = minRef;
+ hasConflict = true;
} else {
fastMinHasMatch = false;
t.matches = t;
}
t.matches = t;
minRef = t;
+ hasConflict = true;
} else
fastMinHasMatch = false;
}
+ if (hasConflict && fastMinHasMatch && dfConflict == null)
+ dfConflict = minRef;
return minRef;
}
for (final AbstractTreeIterator t : trees)
if (t.matches == minRef)
t.matches = treeMatch;
+
+ if (dfConflict == null)
+ dfConflict = treeMatch;
+
return treeMatch;
}
t.matches = null;
}
}
+
+ if (ch == dfConflict)
+ dfConflict = null;
}
@Override
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;
}
}