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 |