import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.nio.file.Files;
import java.util.LinkedHashSet;
import java.util.Set;
writeTrashFile("src/.gitignore", "*\n!*.java\n!*/");
assertSameAsCGit();
}
+
+ @Test
+ public void testMultipleEntriesIgnored() throws Exception {
+ createFiles("dir/a");
+ writeTrashFile(".gitignore", "!dir/a\ndir/a");
+ assertSameAsCGit();
+ }
+
+ @Test
+ public void testMultipleEntriesNotIgnored() throws Exception {
+ createFiles("dir/a");
+ writeTrashFile(".gitignore", "dir/a\n!dir/a");
+ assertSameAsCGit("dir/a");
+ }
+
+ @Test
+ public void testInfoExcludes() throws Exception {
+ createFiles("dir/a", "dir/b");
+ File gitDir = db.getDirectory();
+ File info = new File(gitDir, "info");
+ assertTrue(info.mkdirs());
+ File infoExclude = new File(info, "exclude");
+ Files.writeString(infoExclude.toPath(), "dir/a");
+ assertSameAsCGit("dir/b");
+ }
+
+ @Test
+ public void testInfoExcludesPrecedence() throws Exception {
+ createFiles("dir/a", "dir/b");
+ writeTrashFile(".gitignore", "!dir/a");
+ File gitDir = db.getDirectory();
+ File info = new File(gitDir, "info");
+ assertTrue(info.mkdirs());
+ File infoExclude = new File(info, "exclude");
+ Files.writeString(infoExclude.toPath(), "dir/a");
+ assertSameAsCGit("dir/a", "dir/b");
+ }
+
+ @Test
+ public void testCoreExcludes() throws Exception {
+ createFiles("dir/a", "dir/b");
+ writeTrashFile(".fake_git_ignore", "dir/a");
+ assertSameAsCGit("dir/b");
+ }
+
+ @Test
+ public void testInfoCoreExcludes() throws Exception {
+ createFiles("dir/a", "dir/b");
+ File gitDir = db.getDirectory();
+ File info = new File(gitDir, "info");
+ assertTrue(info.mkdirs());
+ File infoExclude = new File(info, "exclude");
+ Files.writeString(infoExclude.toPath(), "!a");
+ writeTrashFile(".fake_git_ignore", "dir/a");
+ assertSameAsCGit("dir/b");
+ }
+
+ @Test
+ public void testInfoCoreExcludesPrecedence() throws Exception {
+ createFiles("dir/a", "dir/b");
+ File gitDir = db.getDirectory();
+ File info = new File(gitDir, "info");
+ assertTrue(info.mkdirs());
+ File infoExclude = new File(info, "exclude");
+ Files.writeString(infoExclude.toPath(), "!dir/a");
+ writeTrashFile(".fake_git_ignore", "dir/a");
+ assertSameAsCGit("dir/a", "dir/b");
+ }
+
+ @Test
+ public void testInfoCoreExcludesPrecedence2() throws Exception {
+ createFiles("dir/a", "dir/b");
+ File gitDir = db.getDirectory();
+ File info = new File(gitDir, "info");
+ assertTrue(info.mkdirs());
+ File infoExclude = new File(info, "exclude");
+ Files.writeString(infoExclude.toPath(), "dir/a");
+ writeTrashFile(".fake_git_ignore", "!dir/a");
+ assertSameAsCGit("dir/b");
+ }
}
}
IgnoreNode load() throws IOException {
- IgnoreNode r = new IgnoreNode();
+ return load(null);
+ }
+
+ IgnoreNode load(IgnoreNode parent) throws IOException {
+ IgnoreNodeWithParent r = new IgnoreNodeWithParent(parent);
try (InputStream in = entry.openInputStream()) {
r.parse(name, in);
}
- return r.getRules().isEmpty() ? null : r;
+ return r.getRules().isEmpty() && parent == null ? null : r;
}
}
}
@Override
- IgnoreNode load() throws IOException {
- IgnoreNode r;
- if (entry != null) {
- r = super.load();
- if (r == null)
- r = new IgnoreNode();
- } else {
- r = new IgnoreNode();
- }
-
+ IgnoreNode load(IgnoreNode parent) throws IOException {
+ IgnoreNode coreExclude = new IgnoreNodeWithParent(parent);
FS fs = repository.getFS();
Path path = repository.getConfig().getPath(
ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_EXCLUDESFILE, fs, null, null);
if (path != null) {
- loadRulesFromFile(r, path.toFile());
+ loadRulesFromFile(coreExclude, path.toFile());
+ }
+ if (coreExclude.getRules().isEmpty()) {
+ coreExclude = parent;
}
+ IgnoreNode infoExclude = new IgnoreNodeWithParent(
+ coreExclude);
File exclude = fs.resolve(repository.getDirectory(),
Constants.INFO_EXCLUDE);
- loadRulesFromFile(r, exclude);
+ loadRulesFromFile(infoExclude, exclude);
+ if (infoExclude.getRules().isEmpty()) {
+ infoExclude = null;
+ }
- return r.getRules().isEmpty() ? null : r;
+ IgnoreNode parentNode = infoExclude != null ? infoExclude
+ : coreExclude;
+
+ IgnoreNode r;
+ if (entry != null) {
+ r = super.load(parentNode);
+ if (r == null) {
+ return null;
+ }
+ } else {
+ return parentNode;
+ }
+ return r.getRules().isEmpty() ? parentNode : r;
}
private static void loadRulesFromFile(IgnoreNode r, File exclude)
}
}
+ private static class IgnoreNodeWithParent extends IgnoreNode {
+
+ private final IgnoreNode parent;
+
+ IgnoreNodeWithParent(IgnoreNode parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Boolean checkIgnored(String path, boolean isDirectory) {
+ Boolean result = super.checkIgnored(path, isDirectory);
+ if (result == null && parent != null) {
+ return parent.checkIgnored(path, isDirectory);
+ }
+ return result;
+ }
+ }
+
/** Magic type indicating we know rules exist, but they aren't loaded. */
private static class PerDirectoryAttributesNode extends AttributesNode {
final Entry entry;