diff 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
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgIgnore.java	Fri Mar 16 15:06:44 2012 +0100
+++ b/src/org/tmatesoft/hg/repo/HgIgnore.java	Fri Mar 16 20:14:47 2012 +0100
@@ -27,6 +27,7 @@
 import java.util.regex.PatternSyntaxException;
 
 import org.tmatesoft.hg.util.Path;
+import org.tmatesoft.hg.util.PathRewrite;
 
 /**
  * Handling of ignored paths according to .hgignore configuration
@@ -37,12 +38,14 @@
 public class HgIgnore implements Path.Matcher {
 
 	private List<Pattern> entries;
+	private final PathRewrite globPathHelper;
 
-	HgIgnore() {
+	HgIgnore(PathRewrite globPathRewrite) {
 		entries = Collections.emptyList();
+		globPathHelper = globPathRewrite;
 	}
 
-	/* package-local */List<String> read(File hgignoreFile) throws IOException {
+	/* package-local */ List<String> read(File hgignoreFile) throws IOException {
 		if (!hgignoreFile.exists()) {
 			return null;
 		}
@@ -54,7 +57,7 @@
 		}
 	}
 
-	/* package-local */List<String> read(BufferedReader content) throws IOException {
+	/* package-local */ List<String> read(BufferedReader content) throws IOException {
 		final String REGEXP = "regexp", GLOB = "glob";
 		final String REGEXP_PREFIX = REGEXP + ":", GLOB_PREFIX = GLOB + ":";
 		ArrayList<String> errors = new ArrayList<String>();
@@ -101,10 +104,11 @@
 					continue;
 				}
 				if (GLOB.equals(lineSyntax)) {
-					// hgignore(5)
-					// (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters,
-					// hence no special  treatment of Windows path
-					// however, own attempts make me think '\' on Windows are not treated as escapes
+					// hgignore(5) says slashes '\' are escape characters,
+					// however, for glob patterns on Windows first get backslashes converted to slashes
+					if (globPathHelper != null) {
+						line = globPathHelper.rewrite(line).toString();
+					}
 					line = glob2regex(line);
 				} else {
 					assert REGEXP.equals(lineSyntax);
@@ -176,7 +180,13 @@
 			}
 			sb.append(ch);
 		}
-		sb.append("(?:/|$)");
+		// Python impl doesn't keep empty segments in directory names (ntpath.normpath and posixpath.normpath),
+		// effectively removing trailing separators, thus patterns like "bin/" get translated into "bin$"
+		// Our glob rewriter doesn't strip last empty segment, and "bin/$" would be incorrect pattern, 
+		// (e.g. isIgnored("bin/file") performs two matches, against "bin/file" and "bin") hence the check.
+		if (sb.charAt(sb.length() - 1) != '/') {
+			sb.append('$');
+		}
 		return sb.toString();
 	}