Browse Source

Teach NameConflictTreeWalk to report DF conflicts

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>
stable-0.9
Christian Halstrick 15 years ago
parent
commit
74d279fbf0
  1. 55
      org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java
  2. 35
      org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java

55
org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java

@ -120,11 +120,15 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
tw.addTree(new DirCacheIterator(tree1)); tw.addTree(new DirCacheIterator(tree1));
assertModes("a", REGULAR_FILE, TREE, tw); assertModes("a", REGULAR_FILE, TREE, tw);
assertTrue(tw.isDirectoryFileConflict());
assertTrue(tw.isSubtree()); assertTrue(tw.isSubtree());
tw.enterSubtree(); tw.enterSubtree();
assertModes("a/b", MISSING, REGULAR_FILE, tw); assertModes("a/b", MISSING, REGULAR_FILE, tw);
assertTrue(tw.isDirectoryFileConflict());
assertModes("a.b", EXECUTABLE_FILE, MISSING, tw); assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
assertFalse(tw.isDirectoryFileConflict());
assertModes("a0b", SYMLINK, MISSING, tw); assertModes("a0b", SYMLINK, MISSING, tw);
assertFalse(tw.isDirectoryFileConflict());
} }
public void testDF_GapByOne() throws Exception { public void testDF_GapByOne() throws Exception {
@ -153,10 +157,14 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
assertModes("a", REGULAR_FILE, TREE, tw); assertModes("a", REGULAR_FILE, TREE, tw);
assertTrue(tw.isSubtree()); assertTrue(tw.isSubtree());
assertTrue(tw.isDirectoryFileConflict());
tw.enterSubtree(); tw.enterSubtree();
assertModes("a/b", MISSING, REGULAR_FILE, tw); assertModes("a/b", MISSING, REGULAR_FILE, tw);
assertTrue(tw.isDirectoryFileConflict());
assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw); assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw);
assertFalse(tw.isDirectoryFileConflict());
assertModes("a0b", SYMLINK, MISSING, tw); assertModes("a0b", SYMLINK, MISSING, tw);
assertFalse(tw.isDirectoryFileConflict());
} }
public void testDF_SkipsSeenSubtree() throws Exception { public void testDF_SkipsSeenSubtree() throws Exception {
@ -185,10 +193,57 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase {
assertModes("a", REGULAR_FILE, TREE, tw); assertModes("a", REGULAR_FILE, TREE, tw);
assertTrue(tw.isSubtree()); assertTrue(tw.isSubtree());
assertTrue(tw.isDirectoryFileConflict());
tw.enterSubtree(); tw.enterSubtree();
assertModes("a/b", MISSING, REGULAR_FILE, tw); assertModes("a/b", MISSING, REGULAR_FILE, tw);
assertTrue(tw.isDirectoryFileConflict());
assertModes("a.b", MISSING, EXECUTABLE_FILE, tw); assertModes("a.b", MISSING, EXECUTABLE_FILE, tw);
assertFalse(tw.isDirectoryFileConflict());
assertModes("a0b", SYMLINK, SYMLINK, tw); 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 DirCacheEntry makeEntry(final String path, final FileMode mode)

35
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java

@ -87,6 +87,8 @@ public class NameConflictTreeWalk extends TreeWalk {
private boolean fastMinHasMatch; private boolean fastMinHasMatch;
private AbstractTreeIterator dfConflict;
/** /**
* Create a new tree walker for a given repository. * Create a new tree walker for a given repository.
* *
@ -141,6 +143,7 @@ public class NameConflictTreeWalk extends TreeWalk {
if (minRef.eof()) if (minRef.eof())
return minRef; return minRef;
boolean hasConflict = false;
minRef.matches = minRef; minRef.matches = minRef;
while (++i < trees.length) { while (++i < trees.length) {
final AbstractTreeIterator t = trees[i]; final AbstractTreeIterator t = trees[i];
@ -156,6 +159,7 @@ public class NameConflictTreeWalk extends TreeWalk {
// tree anyway. // tree anyway.
// //
t.matches = minRef; t.matches = minRef;
hasConflict = true;
} else { } else {
fastMinHasMatch = false; fastMinHasMatch = false;
t.matches = t; t.matches = t;
@ -182,10 +186,13 @@ public class NameConflictTreeWalk extends TreeWalk {
} }
t.matches = t; t.matches = t;
minRef = t; minRef = t;
hasConflict = true;
} else } else
fastMinHasMatch = false; fastMinHasMatch = false;
} }
if (hasConflict && fastMinHasMatch && dfConflict == null)
dfConflict = minRef;
return minRef; return minRef;
} }
@ -281,6 +288,10 @@ public class NameConflictTreeWalk extends TreeWalk {
for (final AbstractTreeIterator t : trees) for (final AbstractTreeIterator t : trees)
if (t.matches == minRef) if (t.matches == minRef)
t.matches = treeMatch; t.matches = treeMatch;
if (dfConflict == null)
dfConflict = treeMatch;
return treeMatch; return treeMatch;
} }
@ -302,6 +313,9 @@ public class NameConflictTreeWalk extends TreeWalk {
t.matches = null; t.matches = null;
} }
} }
if (ch == dfConflict)
dfConflict = null;
} }
@Override @Override
@ -319,5 +333,26 @@ public class NameConflictTreeWalk extends TreeWalk {
t.matches = null; 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;
} }
} }

Loading…
Cancel
Save