# HG changeset patch # User Artem Tikhomirov # Date 1331906804 -3600 # Node ID e732521a9eb473f25453305b691087815b68205e # Parent 30922c728341f84f09184f7bfe6515c6238f557a Issue 28: support hgignore entries with syntax prefix diff -r 30922c728341 -r e732521a9eb4 src/org/tmatesoft/hg/repo/HgIgnore.java --- a/src/org/tmatesoft/hg/repo/HgIgnore.java Fri Mar 16 12:51:03 2012 +0100 +++ b/src/org/tmatesoft/hg/repo/HgIgnore.java Fri Mar 16 15:06:44 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2011 TMate Software Ltd + * Copyright (c) 2010-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,15 +55,17 @@ } /* package-local */List read(BufferedReader content) throws IOException { + final String REGEXP = "regexp", GLOB = "glob"; + final String REGEXP_PREFIX = REGEXP + ":", GLOB_PREFIX = GLOB + ":"; ArrayList errors = new ArrayList(); ArrayList result = new ArrayList(entries); // start with existing - String syntax = "regexp"; // or "glob" + String syntax = REGEXP; String line; while ((line = content.readLine()) != null) { line = line.trim(); if (line.startsWith("syntax:")) { syntax = line.substring("syntax:".length()).trim(); - if (!"regexp".equals(syntax) && !"glob".equals(syntax)) { + if (!REGEXP.equals(syntax) && !GLOB.equals(syntax)) { errors.add(line); continue; //throw new IllegalStateException(line); @@ -81,17 +83,31 @@ line = line.substring(0, x).trim(); } } + // due to the nature of Mercurial implementation, lines prefixed with syntax kind + // are processed correctly (despite the fact hgignore(5) suggest "syntax:" as the + // only way to specify it). lineSyntax below leaves a chance for the line to switch + // syntax in use without affecting default kind. + String lineSyntax; + if (line.startsWith(GLOB_PREFIX)) { + line = line.substring(GLOB_PREFIX.length()).trim(); + lineSyntax = GLOB; + } else if (line.startsWith(REGEXP_PREFIX)) { + line = line.substring(REGEXP_PREFIX.length()).trim(); + lineSyntax = REGEXP; + } else { + lineSyntax = syntax; + } if (line.length() == 0) { continue; } - if ("glob".equals(syntax)) { + 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 line = glob2regex(line); } else { - assert "regexp".equals(syntax); + assert REGEXP.equals(lineSyntax); // regular expression patterns need not match start of the line unless demanded explicitly line = line.charAt(0) == '^' ? line : ".*" + line; } diff -r 30922c728341 -r e732521a9eb4 test/org/tmatesoft/hg/test/TestIgnore.java --- a/test/org/tmatesoft/hg/test/TestIgnore.java Fri Mar 16 12:51:03 2012 +0100 +++ b/test/org/tmatesoft/hg/test/TestIgnore.java Fri Mar 16 15:06:44 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.test; +import static org.tmatesoft.hg.util.Path.create; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -152,4 +154,28 @@ errorCollector.assertTrue(p.toString(), !hgIgnore.isIgnored(p)); } } + + @Test + public void testSyntaxPrefixAtLine() throws Exception { + String s = "glob:*.c\nregexp:.*\\.d"; + HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s)); + Path[] toPass = new Path[] { + create("a/c"), + create("a/d"), + create("a/d.a"), + create("a/d.e"), + }; + Path[] toIgnore = new Path[] { + create("a.c"), + create("a.d"), + create("src/a.c"), + create("src/a.d"), + }; + for (Path p : toIgnore) { + errorCollector.assertTrue("Shall ignore " + p, hgIgnore.isIgnored(p)); + } + for (Path p : toPass) { + errorCollector.assertTrue("Shall pass " + p, !hgIgnore.isIgnored(p)); + } + } }