diff options
author | Marc Strapetz <marc.strapetz@syntevo.com> | 2018-02-23 13:34:23 +0100 |
---|---|---|
committer | Marc Strapetz <marc.strapetz@syntevo.com> | 2018-02-23 13:36:48 +0100 |
commit | 78420b7d0a65d591d00f32675efb0a42cda6c84a (patch) | |
tree | 01dc25fc81bc3c35b72e975b37ea18ba5a9b6398 /org.eclipse.jgit.test | |
parent | 152d5e2a14f2c03d55776154f67fab3f408a57e0 (diff) | |
download | jgit-78420b7d0a65d591d00f32675efb0a42cda6c84a.tar.gz jgit-78420b7d0a65d591d00f32675efb0a42cda6c84a.zip |
Fix processing of gitignore negations
Processing of negated rules, like !bin/ was not working correctly: they
were interpreted too broad, resulting in unexpected untracked files
which should actually be ignored
Bug: 409664
Change-Id: I0a422fd6607941461bf2175c9105a0311612efa0
Signed-off-by: Marc Strapetz <marc.strapetz@syntevo.com>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java | 64 | ||||
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java | 233 |
2 files changed, 296 insertions, 1 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java index 155bd27303..3b11616fe6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java @@ -321,4 +321,68 @@ public class CGitIgnoreTest extends RepositoryTestCase { writeTrashFile(".gitignore", "[\\[\\]]\n"); assertSameAsCGit(); } + + @Test + public void testSimpleRootGitIgnoreGlobalNegation1() throws Exception { + // see IgnoreNodeTest.testSimpleRootGitIgnoreGlobalNegation1 + createFiles("x1", "a/x2", "x3/y"); + writeTrashFile(".gitignore", "*\n!x*"); + assertSameAsCGit(); + } + + @Test + public void testRepeatedNegationInDifferentFiles5() throws Exception { + // see IgnoreNodeTest.testRepeatedNegationInDifferentFiles5 + createFiles("a/b/e/nothere.o"); + writeTrashFile(".gitignore", "e"); + writeTrashFile("a/.gitignore", "e"); + writeTrashFile("a/b/.gitignore", "!e"); + assertSameAsCGit(); + } + + @Test + public void testRepeatedNegationInDifferentFilesWithWildmatcher1() + throws Exception { + createFiles("e", "x/e/f", "a/e/x1", "a/e/x2", "a/e/y", "a/e/sub/y"); + writeTrashFile(".gitignore", "a/e/**"); + writeTrashFile("a/.gitignore", "!e/x*"); + assertSameAsCGit(); + } + + @Test + public void testRepeatedNegationInDifferentFilesWithWildmatcher2() + throws Exception { + createFiles("e", "dir/f", "dir/g/h", "a/dir/i", "a/dir/j/k", + "a/b/dir/l", "a/b/dir/m/n", "a/b/dir/m/o/p", "a/q/dir/r", + "a/q/dir/dir/s", "c/d/dir/x", "c/d/dir/y"); + writeTrashFile(".gitignore", "**/dir/*"); + writeTrashFile("a/.gitignore", "!dir/*"); + writeTrashFile("a/b/.gitignore", "!**/dir/*"); + writeTrashFile("c/.gitignore", "!d/dir/x"); + assertSameAsCGit(); + } + + @Test + public void testNegationForSubDirectoryWithinIgnoredDirectoryHasNoEffect1() + throws Exception { + createFiles("e", "a/f", "a/b/g", "a/b/h/i"); + writeTrashFile(".gitignore", "a/b"); + writeTrashFile("a/.gitignore", "!b/*"); + assertSameAsCGit(); + } + + /* + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=407475 + */ + @Test + public void testNegationAllExceptJavaInSrcAndExceptChildDirInSrc() + throws Exception { + // see + // IgnoreNodeTest.testNegationAllExceptJavaInSrcAndExceptChildDirInSrc + createFiles("nothere.o", "src/keep.java", "src/nothere.o", + "src/a/keep.java", "src/a/keep.o"); + writeTrashFile(".gitignore", "/*\n!/src/"); + writeTrashFile("src/.gitignore", "*\n!*.java\n!*/"); + assertSameAsCGit(); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java index 1178eb3e8a..1a02df466d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java @@ -81,6 +81,141 @@ public class IgnoreNodeTest extends RepositoryTestCase { private TreeWalk walk; @Test + public void testSimpleRootGitIgnoreGlobalIgnore() throws IOException { + writeIgnoreFile(".gitignore", "x"); + + writeTrashFile("a/x/file", ""); + writeTrashFile("b/x", ""); + writeTrashFile("x/file", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(D, ignored, "a/x"); + assertEntry(F, ignored, "a/x/file"); + assertEntry(D, tracked, "b"); + assertEntry(F, ignored, "b/x"); + assertEntry(D, ignored, "x"); + assertEntry(F, ignored, "x/file"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreGlobalDirIgnore() throws IOException { + writeIgnoreFile(".gitignore", "x/"); + + writeTrashFile("a/x/file", ""); + writeTrashFile("x/file", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(D, ignored, "a/x"); + assertEntry(F, ignored, "a/x/file"); + assertEntry(D, ignored, "x"); + assertEntry(F, ignored, "x/file"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreWildMatcher() throws IOException { + writeIgnoreFile(".gitignore", "**"); + + writeTrashFile("a/x", ""); + writeTrashFile("y", ""); + + beginWalk(); + assertEntry(F, ignored, ".gitignore"); + assertEntry(D, ignored, "a"); + assertEntry(F, ignored, "a/x"); + assertEntry(F, ignored, "y"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreWildMatcherDirOnly() throws IOException { + writeIgnoreFile(".gitignore", "**/"); + + writeTrashFile("a/x", ""); + writeTrashFile("y", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, ignored, "a"); + assertEntry(F, ignored, "a/x"); + assertEntry(F, tracked, "y"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreGlobalNegation1() throws IOException { + writeIgnoreFile(".gitignore", "*", "!x*"); + writeTrashFile("x1", ""); + writeTrashFile("a/x2", ""); + writeTrashFile("x3/y", ""); + + beginWalk(); + assertEntry(F, ignored, ".gitignore"); + assertEntry(D, ignored, "a"); + assertEntry(F, ignored, "a/x2"); + assertEntry(F, tracked, "x1"); + assertEntry(D, tracked, "x3"); + assertEntry(F, ignored, "x3/y"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreGlobalNegation2() throws IOException { + writeIgnoreFile(".gitignore", "*", "!x*", "!/a"); + writeTrashFile("x1", ""); + writeTrashFile("a/x2", ""); + writeTrashFile("x3/y", ""); + + beginWalk(); + assertEntry(F, ignored, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(F, tracked, "a/x2"); + assertEntry(F, tracked, "x1"); + assertEntry(D, tracked, "x3"); + assertEntry(F, ignored, "x3/y"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreGlobalNegation3() throws IOException { + writeIgnoreFile(".gitignore", "*", "!x*", "!x*/**"); + writeTrashFile("x1", ""); + writeTrashFile("a/x2", ""); + writeTrashFile("x3/y", ""); + + beginWalk(); + assertEntry(F, ignored, ".gitignore"); + assertEntry(D, ignored, "a"); + assertEntry(F, ignored, "a/x2"); + assertEntry(F, tracked, "x1"); + assertEntry(D, tracked, "x3"); + assertEntry(F, tracked, "x3/y"); + endWalk(); + } + + @Test + public void testSimpleRootGitIgnoreGlobalNegation4() throws IOException { + writeIgnoreFile(".gitignore", "*", "!**/"); + writeTrashFile("x1", ""); + writeTrashFile("a/x2", ""); + writeTrashFile("x3/y", ""); + + beginWalk(); + assertEntry(F, ignored, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(F, ignored, "a/x2"); + assertEntry(F, ignored, "x1"); + assertEntry(D, tracked, "x3"); + assertEntry(F, ignored, "x3/y"); + endWalk(); + } + + @Test public void testRules() throws IOException { writeIgnoreFile(".git/info/exclude", "*~", "/out"); @@ -210,7 +345,7 @@ public class IgnoreNodeTest extends RepositoryTestCase { assertEntry(F, ignored, "src/.gitignore"); assertEntry(D, tracked, "src/a"); assertEntry(F, tracked, "src/a/keep.java"); - assertEntry(F, tracked, "src/a/keep.o"); + assertEntry(F, ignored, "src/a/keep.o"); assertEntry(F, tracked, "src/keep.java"); assertEntry(F, ignored, "src/nothere.o"); endWalk(); @@ -316,6 +451,102 @@ public class IgnoreNodeTest extends RepositoryTestCase { } @Test + public void testRepeatedNegationInDifferentFiles5() throws IOException { + writeIgnoreFile(".gitignore", "e"); + writeIgnoreFile("a/.gitignore", "e"); + writeIgnoreFile("a/b/.gitignore", "!e"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(F, tracked, "a/.gitignore"); + assertEntry(D, tracked, "a/b"); + assertEntry(F, tracked, "a/b/.gitignore"); + assertEntry(D, tracked, "a/b/e"); + assertEntry(F, tracked, "a/b/e/nothere.o"); + endWalk(); + } + + @Test + public void testIneffectiveNegationDifferentLevels1() throws IOException { + writeIgnoreFile(".gitignore", "a/b/e/", "!a/b/e/*"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(D, tracked, "a/b"); + assertEntry(D, ignored, "a/b/e"); + assertEntry(F, ignored, "a/b/e/nothere.o"); + endWalk(); + } + + @Test + public void testIneffectiveNegationDifferentLevels2() throws IOException { + writeIgnoreFile(".gitignore", "a/b/e/"); + writeIgnoreFile("a/.gitignore", "!b/e/*"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(F, tracked, "a/.gitignore"); + assertEntry(D, tracked, "a/b"); + assertEntry(D, ignored, "a/b/e"); + assertEntry(F, ignored, "a/b/e/nothere.o"); + endWalk(); + } + + @Test + public void testIneffectiveNegationDifferentLevels3() throws IOException { + writeIgnoreFile(".gitignore", "a/b/e/"); + writeIgnoreFile("a/b/.gitignore", "!e/*"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(D, tracked, "a/b"); + assertEntry(F, tracked, "a/b/.gitignore"); + assertEntry(D, ignored, "a/b/e"); + assertEntry(F, ignored, "a/b/e/nothere.o"); + endWalk(); + } + + @Test + public void testIneffectiveNegationDifferentLevels4() throws IOException { + writeIgnoreFile(".gitignore", "a/b/e/"); + writeIgnoreFile("a/b/e/.gitignore", "!*"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(F, tracked, ".gitignore"); + assertEntry(D, tracked, "a"); + assertEntry(D, tracked, "a/b"); + assertEntry(D, ignored, "a/b/e"); + assertEntry(F, ignored, "a/b/e/.gitignore"); + assertEntry(F, ignored, "a/b/e/nothere.o"); + endWalk(); + } + + @Test + public void testIneffectiveNegationDifferentLevels5() throws IOException { + writeIgnoreFile("a/.gitignore", "b/e/"); + writeIgnoreFile("a/b/.gitignore", "!e/*"); + writeTrashFile("a/b/e/nothere.o", ""); + + beginWalk(); + assertEntry(D, tracked, "a"); + assertEntry(F, tracked, "a/.gitignore"); + assertEntry(D, tracked, "a/b"); + assertEntry(F, tracked, "a/b/.gitignore"); + assertEntry(D, ignored, "a/b/e"); + assertEntry(F, ignored, "a/b/e/nothere.o"); + endWalk(); + } + + @Test public void testEmptyIgnoreNode() { // Rules are never empty: WorkingTreeIterator optimizes empty files away // So we have to test it manually in case third party clients use |