Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgIgnore.java @ 409:0f5696623512 smartgit3
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Fri, 16 Mar 2012 20:14:47 +0100 |
| parents | e732521a9eb4 |
| children | 7f136a3fa671 |
comparison
equal
deleted
inserted
replaced
| 408:e732521a9eb4 | 409:0f5696623512 |
|---|---|
| 25 import java.util.List; | 25 import java.util.List; |
| 26 import java.util.regex.Pattern; | 26 import java.util.regex.Pattern; |
| 27 import java.util.regex.PatternSyntaxException; | 27 import java.util.regex.PatternSyntaxException; |
| 28 | 28 |
| 29 import org.tmatesoft.hg.util.Path; | 29 import org.tmatesoft.hg.util.Path; |
| 30 import org.tmatesoft.hg.util.PathRewrite; | |
| 30 | 31 |
| 31 /** | 32 /** |
| 32 * Handling of ignored paths according to .hgignore configuration | 33 * Handling of ignored paths according to .hgignore configuration |
| 33 * | 34 * |
| 34 * @author Artem Tikhomirov | 35 * @author Artem Tikhomirov |
| 35 * @author TMate Software Ltd. | 36 * @author TMate Software Ltd. |
| 36 */ | 37 */ |
| 37 public class HgIgnore implements Path.Matcher { | 38 public class HgIgnore implements Path.Matcher { |
| 38 | 39 |
| 39 private List<Pattern> entries; | 40 private List<Pattern> entries; |
| 40 | 41 private final PathRewrite globPathHelper; |
| 41 HgIgnore() { | 42 |
| 43 HgIgnore(PathRewrite globPathRewrite) { | |
| 42 entries = Collections.emptyList(); | 44 entries = Collections.emptyList(); |
| 43 } | 45 globPathHelper = globPathRewrite; |
| 44 | 46 } |
| 45 /* package-local */List<String> read(File hgignoreFile) throws IOException { | 47 |
| 48 /* package-local */ List<String> read(File hgignoreFile) throws IOException { | |
| 46 if (!hgignoreFile.exists()) { | 49 if (!hgignoreFile.exists()) { |
| 47 return null; | 50 return null; |
| 48 } | 51 } |
| 49 BufferedReader fr = new BufferedReader(new FileReader(hgignoreFile)); | 52 BufferedReader fr = new BufferedReader(new FileReader(hgignoreFile)); |
| 50 try { | 53 try { |
| 52 } finally { | 55 } finally { |
| 53 fr.close(); | 56 fr.close(); |
| 54 } | 57 } |
| 55 } | 58 } |
| 56 | 59 |
| 57 /* package-local */List<String> read(BufferedReader content) throws IOException { | 60 /* package-local */ List<String> read(BufferedReader content) throws IOException { |
| 58 final String REGEXP = "regexp", GLOB = "glob"; | 61 final String REGEXP = "regexp", GLOB = "glob"; |
| 59 final String REGEXP_PREFIX = REGEXP + ":", GLOB_PREFIX = GLOB + ":"; | 62 final String REGEXP_PREFIX = REGEXP + ":", GLOB_PREFIX = GLOB + ":"; |
| 60 ArrayList<String> errors = new ArrayList<String>(); | 63 ArrayList<String> errors = new ArrayList<String>(); |
| 61 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing | 64 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing |
| 62 String syntax = REGEXP; | 65 String syntax = REGEXP; |
| 99 } | 102 } |
| 100 if (line.length() == 0) { | 103 if (line.length() == 0) { |
| 101 continue; | 104 continue; |
| 102 } | 105 } |
| 103 if (GLOB.equals(lineSyntax)) { | 106 if (GLOB.equals(lineSyntax)) { |
| 104 // hgignore(5) | 107 // hgignore(5) says slashes '\' are escape characters, |
| 105 // (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters, | 108 // however, for glob patterns on Windows first get backslashes converted to slashes |
| 106 // hence no special treatment of Windows path | 109 if (globPathHelper != null) { |
| 107 // however, own attempts make me think '\' on Windows are not treated as escapes | 110 line = globPathHelper.rewrite(line).toString(); |
| 111 } | |
| 108 line = glob2regex(line); | 112 line = glob2regex(line); |
| 109 } else { | 113 } else { |
| 110 assert REGEXP.equals(lineSyntax); | 114 assert REGEXP.equals(lineSyntax); |
| 111 // regular expression patterns need not match start of the line unless demanded explicitly | 115 // regular expression patterns need not match start of the line unless demanded explicitly |
| 112 line = line.charAt(0) == '^' ? line : ".*" + line; | 116 line = line.charAt(0) == '^' ? line : ".*" + line; |
| 174 sb.append('|'); | 178 sb.append('|'); |
| 175 continue; | 179 continue; |
| 176 } | 180 } |
| 177 sb.append(ch); | 181 sb.append(ch); |
| 178 } | 182 } |
| 179 sb.append("(?:/|$)"); | 183 // Python impl doesn't keep empty segments in directory names (ntpath.normpath and posixpath.normpath), |
| 184 // effectively removing trailing separators, thus patterns like "bin/" get translated into "bin$" | |
| 185 // Our glob rewriter doesn't strip last empty segment, and "bin/$" would be incorrect pattern, | |
| 186 // (e.g. isIgnored("bin/file") performs two matches, against "bin/file" and "bin") hence the check. | |
| 187 if (sb.charAt(sb.length() - 1) != '/') { | |
| 188 sb.append('$'); | |
| 189 } | |
| 180 return sb.toString(); | 190 return sb.toString(); |
| 181 } | 191 } |
| 182 | 192 |
| 183 /** | 193 /** |
| 184 * @param path file or directory name in question | 194 * @param path file or directory name in question |
