Browse Source

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>
tags/v5.11.0.202102240950-m3
Thomas Wolf 3 years ago
parent
commit
29697d86c5

+ 1
- 0
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties View File

@@ -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}

+ 22
- 16
org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java View File

@@ -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);
}

/**

+ 43
- 3
org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java View File

@@ -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++;
}
}


+ 1
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java View File

@@ -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;

+ 13
- 7
org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java View File

@@ -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);
}
}
}

Loading…
Cancel
Save