You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IgnoreNode.java 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (C) 2010, Red Hat Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.ignore;
  11. import static java.nio.charset.StandardCharsets.UTF_8;
  12. import java.io.BufferedReader;
  13. import java.io.IOException;
  14. import java.io.InputStream;
  15. import java.io.InputStreamReader;
  16. import java.util.ArrayList;
  17. import java.util.Collections;
  18. import java.util.List;
  19. /**
  20. * Represents a bundle of ignore rules inherited from a base directory.
  21. *
  22. * This class is not thread safe, it maintains state about the last match.
  23. */
  24. public class IgnoreNode {
  25. /** Result from {@link IgnoreNode#isIgnored(String, boolean)}. */
  26. public enum MatchResult {
  27. /** The file is not ignored, due to a rule saying its not ignored. */
  28. NOT_IGNORED,
  29. /** The file is ignored due to a rule in this node. */
  30. IGNORED,
  31. /** The ignore status is unknown, check inherited rules. */
  32. CHECK_PARENT,
  33. /**
  34. * The first previous (parent) ignore rule match (if any) should be
  35. * negated, and then inherited rules applied.
  36. *
  37. * @since 3.6
  38. */
  39. CHECK_PARENT_NEGATE_FIRST_MATCH;
  40. }
  41. /** The rules that have been parsed into this node. */
  42. private final List<FastIgnoreRule> rules;
  43. /**
  44. * Create an empty ignore node with no rules.
  45. */
  46. public IgnoreNode() {
  47. rules = new ArrayList<>();
  48. }
  49. /**
  50. * Create an ignore node with given rules.
  51. *
  52. * @param rules
  53. * list of rules.
  54. */
  55. public IgnoreNode(List<FastIgnoreRule> rules) {
  56. this.rules = rules;
  57. }
  58. /**
  59. * Parse files according to gitignore standards.
  60. *
  61. * @param in
  62. * input stream holding the standard ignore format. The caller is
  63. * responsible for closing the stream.
  64. * @throws java.io.IOException
  65. * Error thrown when reading an ignore file.
  66. */
  67. public void parse(InputStream in) throws IOException {
  68. BufferedReader br = asReader(in);
  69. String txt;
  70. while ((txt = br.readLine()) != null) {
  71. if (txt.length() > 0 && !txt.startsWith("#") && !txt.equals("/")) { //$NON-NLS-1$ //$NON-NLS-2$
  72. FastIgnoreRule rule = new FastIgnoreRule(txt);
  73. if (!rule.isEmpty()) {
  74. rules.add(rule);
  75. }
  76. }
  77. }
  78. }
  79. private static BufferedReader asReader(InputStream in) {
  80. return new BufferedReader(new InputStreamReader(in, UTF_8));
  81. }
  82. /**
  83. * Get list of all ignore rules held by this node
  84. *
  85. * @return list of all ignore rules held by this node
  86. */
  87. public List<FastIgnoreRule> getRules() {
  88. return Collections.unmodifiableList(rules);
  89. }
  90. /**
  91. * Determine if an entry path matches an ignore rule.
  92. *
  93. * @param entryPath
  94. * the path to test. The path must be relative to this ignore
  95. * node's own repository path, and in repository path format
  96. * (uses '/' and not '\').
  97. * @param isDirectory
  98. * true if the target item is a directory.
  99. * @return status of the path.
  100. */
  101. public MatchResult isIgnored(String entryPath, boolean isDirectory) {
  102. final Boolean result = checkIgnored(entryPath, isDirectory);
  103. if (result == null) {
  104. return MatchResult.CHECK_PARENT;
  105. }
  106. return result.booleanValue() ? MatchResult.IGNORED
  107. : MatchResult.NOT_IGNORED;
  108. }
  109. /**
  110. * Determine if an entry path matches an ignore rule.
  111. *
  112. * @param entryPath
  113. * the path to test. The path must be relative to this ignore
  114. * node's own repository path, and in repository path format
  115. * (uses '/' and not '\').
  116. * @param isDirectory
  117. * true if the target item is a directory.
  118. * @return Boolean.TRUE, if the entry is ignored; Boolean.FALSE, if the
  119. * entry is forced to be not ignored (negated match); or null, if
  120. * undetermined
  121. * @since 4.11
  122. */
  123. public Boolean checkIgnored(String entryPath, boolean isDirectory) {
  124. // Parse rules in the reverse order that they were read because later
  125. // rules have higher priority
  126. for (int i = rules.size() - 1; i > -1; i--) {
  127. FastIgnoreRule rule = rules.get(i);
  128. if (rule.isMatch(entryPath, isDirectory, true)) {
  129. return Boolean.valueOf(rule.getResult());
  130. }
  131. }
  132. return null;
  133. }
  134. /** {@inheritDoc} */
  135. @Override
  136. public String toString() {
  137. return rules.toString();
  138. }
  139. }