aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2021-02-23 18:10:08 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2021-02-23 22:11:01 +0100
commit29697d86c5f66983feda94623477688211d06bde (patch)
tree455a5e917bb0e4745474a7aca30c48a41accce7c
parent4e745c57f7612123bc58d3ff96f95c472f9edc94 (diff)
downloadjgit-29697d86c5f66983feda94623477688211d06bde.tar.gz
jgit-29697d86c5f66983feda94623477688211d06bde.zip
IgnoreNode: include path to file for invalid .gitignore patterns
Include the full file path of the .gitignore file and the line number of the invalid pattern. Also include the pattern itself. .gitignore files inside the repository are reported with their repository-relative path; files outside (from git config core.excludesFile or .git/info/exclude) are reported with their full absolute path. Bug: 571143 Change-Id: Ibe5969679bc22cff923c62e3ab9801d90d6d06d1 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java38
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java46
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java20
5 files changed, 80 insertions, 26 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 9ec2c7d743..c00203dd07 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -31,6 +31,7 @@ badEntryName=Bad entry name: {0}
badEscape=Bad escape: {0}
badGroupHeader=Bad group header
badIgnorePattern=Cannot parse .gitignore pattern ''{0}''
+badIgnorePatternFull=File {0} line {1}: cannot parse pattern ''{2}'': {3}
badObjectType=Bad object type: {0}
badRef=Bad ref: {0}: {1}
badSectionEntry=Bad section entry: {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
index 8b35406e3d..9dd565ff0a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de> and others
+ * Copyright (C) 2014, 2021 Andrey Loskutov <loskutov@gmx.de> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -39,11 +39,11 @@ public class FastIgnoreRule {
*/
public static final char PATH_SEPARATOR = '/';
- private final IMatcher matcher;
+ private IMatcher matcher;
- private final boolean inverse;
+ private boolean inverse;
- private final boolean dirOnly;
+ private boolean dirOnly;
/**
* Constructor for FastIgnoreRule
@@ -55,8 +55,23 @@ public class FastIgnoreRule {
* (comment), this rule doesn't match anything.
*/
public FastIgnoreRule(String pattern) {
- if (pattern == null)
+ this();
+ try {
+ parse(pattern);
+ } catch (InvalidPatternException e) {
+ LOG.error(MessageFormat.format(JGitText.get().badIgnorePattern,
+ e.getPattern()), e);
+ }
+ }
+
+ FastIgnoreRule() {
+ matcher = IMatcher.NO_MATCH;
+ }
+
+ void parse(String pattern) throws InvalidPatternException {
+ if (pattern == null) {
throw new IllegalArgumentException("Pattern must not be null!"); //$NON-NLS-1$
+ }
if (pattern.length() == 0) {
dirOnly = false;
inverse = false;
@@ -93,17 +108,8 @@ public class FastIgnoreRule {
return;
}
}
- IMatcher m;
- try {
- m = PathMatcher.createPathMatcher(pattern,
- Character.valueOf(PATH_SEPARATOR), dirOnly);
- } catch (InvalidPatternException e) {
- m = NO_MATCH;
- LOG.error(MessageFormat.format(
- JGitText.get().badIgnorePattern,
- e.getPattern()), e);
- }
- this.matcher = m;
+ this.matcher = PathMatcher.createPathMatcher(pattern,
+ Character.valueOf(PATH_SEPARATOR), dirOnly);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
index 1a1b2d302f..4e7f126a60 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, Red Hat Inc. and others
+ * Copyright (C) 2010, 2021 Red Hat Inc. and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -15,11 +15,16 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.errors.InvalidPatternException;
+import org.eclipse.jgit.internal.JGitText;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Represents a bundle of ignore rules inherited from a base directory.
@@ -27,6 +32,9 @@ import org.eclipse.jgit.annotations.Nullable;
* This class is not thread safe, it maintains state about the last match.
*/
public class IgnoreNode {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IgnoreNode.class);
+
/** Result from {@link IgnoreNode#isIgnored(String, boolean)}. */
public enum MatchResult {
/** The file is not ignored, due to a rule saying its not ignored. */
@@ -54,7 +62,7 @@ public class IgnoreNode {
* Create an empty ignore node with no rules.
*/
public IgnoreNode() {
- rules = new ArrayList<>();
+ this(new ArrayList<>());
}
/**
@@ -77,15 +85,47 @@ public class IgnoreNode {
* Error thrown when reading an ignore file.
*/
public void parse(InputStream in) throws IOException {
+ parse(null, in);
+ }
+
+ /**
+ * Parse files according to gitignore standards.
+ *
+ * @param sourceName
+ * identifying the source of the stream
+ * @param in
+ * input stream holding the standard ignore format. The caller is
+ * responsible for closing the stream.
+ * @throws java.io.IOException
+ * Error thrown when reading an ignore file.
+ * @since 5.11
+ */
+ public void parse(String sourceName, InputStream in) throws IOException {
BufferedReader br = asReader(in);
String txt;
+ int lineNumber = 1;
while ((txt = br.readLine()) != null) {
if (txt.length() > 0 && !txt.startsWith("#") && !txt.equals("/")) { //$NON-NLS-1$ //$NON-NLS-2$
- FastIgnoreRule rule = new FastIgnoreRule(txt);
+ FastIgnoreRule rule = new FastIgnoreRule();
+ try {
+ rule.parse(txt);
+ } catch (InvalidPatternException e) {
+ if (sourceName != null) {
+ LOG.error(MessageFormat.format(
+ JGitText.get().badIgnorePatternFull, sourceName,
+ Integer.toString(lineNumber), e.getPattern(),
+ e.getLocalizedMessage()), e);
+ } else {
+ LOG.error(MessageFormat.format(
+ JGitText.get().badIgnorePattern,
+ e.getPattern()), e);
+ }
+ }
if (!rule.isEmpty()) {
rules.add(rule);
}
}
+ lineNumber++;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index cf915afdc1..9d215ca455 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -59,6 +59,7 @@ public class JGitText extends TranslationBundle {
/***/ public String badEscape;
/***/ public String badGroupHeader;
/***/ public String badIgnorePattern;
+ /***/ public String badIgnorePatternFull;
/***/ public String badObjectType;
/***/ public String badRef;
/***/ public String badSectionEntry;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 6faf42bcf8..55b7d6279a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -2,7 +2,7 @@
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
* Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- * Copyright (C) 2012-2020, Robin Rosenberg and others
+ * Copyright (C) 2012-2021, Robin Rosenberg and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -800,7 +800,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
if (Constants.DOT_GIT.equals(name))
continue;
if (Constants.DOT_GIT_IGNORE.equals(name))
- ignoreNode = new PerDirectoryIgnoreNode(e);
+ ignoreNode = new PerDirectoryIgnoreNode(
+ TreeWalk.pathOf(path, 0, pathOffset)
+ + Constants.DOT_GIT_IGNORE,
+ e);
if (Constants.DOT_GIT_ATTRIBUTES.equals(name))
attributesNode = new PerDirectoryAttributesNode(e);
if (i != o)
@@ -1274,17 +1277,20 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
/** Magic type indicating we know rules exist, but they aren't loaded. */
private static class PerDirectoryIgnoreNode extends IgnoreNode {
- final Entry entry;
+ protected final Entry entry;
+
+ private final String name;
- PerDirectoryIgnoreNode(Entry entry) {
+ PerDirectoryIgnoreNode(String name, Entry entry) {
super(Collections.<FastIgnoreRule> emptyList());
+ this.name = name;
this.entry = entry;
}
IgnoreNode load() throws IOException {
IgnoreNode r = new IgnoreNode();
try (InputStream in = entry.openInputStream()) {
- r.parse(in);
+ r.parse(name, in);
}
return r.getRules().isEmpty() ? null : r;
}
@@ -1295,7 +1301,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
final Repository repository;
RootIgnoreNode(Entry entry, Repository repository) {
- super(entry);
+ super(entry != null ? entry.getName() : null, entry);
this.repository = repository;
}
@@ -1329,7 +1335,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
throws FileNotFoundException, IOException {
if (FS.DETECTED.exists(exclude)) {
try (FileInputStream in = new FileInputStream(exclude)) {
- r.parse(in);
+ r.parse(exclude.getAbsolutePath(), in);
}
}
}