The WorkingTreeIterator.isEntryIgnored() should use originally requested file mode while descending to the file tree root and checking ignore rules. Original code asking isEntryIgnored() on a file was using directory mode instead if the .gitignore was not located in the same directory. Bug: 473506 Change-Id: I9f16ba714c3ea9e6585e9c11623270dbdf4fb1df Signed-off-by: Andrey Loskutov <loskutov@gmx.de>tags/v4.1.0.201509280440-r
@@ -354,6 +354,56 @@ public class IgnoreNodeTest extends RepositoryTestCase { | |||
endWalk(); | |||
} | |||
@Test | |||
public void testSlashMatchesDirectory() throws IOException { | |||
writeIgnoreFile(".gitignore", "out2/"); | |||
writeTrashFile("out1/out1", ""); | |||
writeTrashFile("out1/out2", ""); | |||
writeTrashFile("out2/out1", ""); | |||
writeTrashFile("out2/out2", ""); | |||
beginWalk(); | |||
assertEntry(F, tracked, ".gitignore"); | |||
assertEntry(D, tracked, "out1"); | |||
assertEntry(F, tracked, "out1/out1"); | |||
assertEntry(F, tracked, "out1/out2"); | |||
assertEntry(D, ignored, "out2"); | |||
assertEntry(F, ignored, "out2/out1"); | |||
assertEntry(F, ignored, "out2/out2"); | |||
endWalk(); | |||
} | |||
@Test | |||
public void testWildcardWithSlashMatchesDirectory() throws IOException { | |||
writeIgnoreFile(".gitignore", "out2*/"); | |||
writeTrashFile("out1/out1.txt", ""); | |||
writeTrashFile("out1/out2", ""); | |||
writeTrashFile("out1/out2.txt", ""); | |||
writeTrashFile("out1/out2x/a", ""); | |||
writeTrashFile("out2/out1.txt", ""); | |||
writeTrashFile("out2/out2.txt", ""); | |||
writeTrashFile("out2x/out1.txt", ""); | |||
writeTrashFile("out2x/out2.txt", ""); | |||
beginWalk(); | |||
assertEntry(F, tracked, ".gitignore"); | |||
assertEntry(D, tracked, "out1"); | |||
assertEntry(F, tracked, "out1/out1.txt"); | |||
assertEntry(F, tracked, "out1/out2"); | |||
assertEntry(F, tracked, "out1/out2.txt"); | |||
assertEntry(D, ignored, "out1/out2x"); | |||
assertEntry(F, ignored, "out1/out2x/a"); | |||
assertEntry(D, ignored, "out2"); | |||
assertEntry(F, ignored, "out2/out1.txt"); | |||
assertEntry(F, ignored, "out2/out2.txt"); | |||
assertEntry(D, ignored, "out2x"); | |||
assertEntry(F, ignored, "out2x/out1.txt"); | |||
assertEntry(F, ignored, "out2x/out2.txt"); | |||
endWalk(); | |||
} | |||
@Test | |||
public void testWithSlashDoesNotMatchInSubDirectory() throws IOException { | |||
writeIgnoreFile(".gitignore", "a/b"); |
@@ -596,7 +596,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { | |||
* a relevant ignore rule file exists but cannot be read. | |||
*/ | |||
protected boolean isEntryIgnored(final int pLen) throws IOException { | |||
return isEntryIgnored(pLen, false); | |||
return isEntryIgnored(pLen, mode, false); | |||
} | |||
/** | |||
@@ -605,13 +605,16 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { | |||
* | |||
* @param pLen | |||
* the length of the path in the path buffer. | |||
* @param fileMode | |||
* the original iterator file mode | |||
* @param negatePrevious | |||
* true if the previous matching iterator rule was negation | |||
* @return true if the entry is ignored by an ignore rule. | |||
* @throws IOException | |||
* a relevant ignore rule file exists but cannot be read. | |||
*/ | |||
private boolean isEntryIgnored(final int pLen, boolean negatePrevious) | |||
private boolean isEntryIgnored(final int pLen, int fileMode, | |||
boolean negatePrevious) | |||
throws IOException { | |||
IgnoreNode rules = getIgnoreNode(); | |||
if (rules != null) { | |||
@@ -623,7 +626,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { | |||
if (0 < pOff) | |||
pOff--; | |||
String p = TreeWalk.pathOf(path, pOff, pLen); | |||
switch (rules.isIgnored(p, FileMode.TREE.equals(mode), | |||
switch (rules.isIgnored(p, FileMode.TREE.equals(fileMode), | |||
negatePrevious)) { | |||
case IGNORED: | |||
return true; | |||
@@ -638,7 +641,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { | |||
} | |||
} | |||
if (parent instanceof WorkingTreeIterator) | |||
return ((WorkingTreeIterator) parent).isEntryIgnored(pLen, | |||
return ((WorkingTreeIterator) parent).isEntryIgnored(pLen, fileMode, | |||
negatePrevious); | |||
return false; | |||
} |