Mercurial > jhg
annotate src/org/tmatesoft/hg/repo/HgIgnore.java @ 709:497e697636fc
Report merged lines as changed block if possible, not as a sequence of added/deleted blocks. To facilitate access to merge parent lines AddBlock got mergeLineAt() method that reports index of the line in the second parent (if any), while insertedAt() has been changed to report index in the first parent always
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 21 Aug 2013 16:23:27 +0200 |
parents | 7efabe0cddcf |
children |
rev | line source |
---|---|
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
1 /* |
564
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
2 * Copyright (c) 2010-2013 TMate Software Ltd |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
3 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
6 * the Free Software Foundation; version 2 of the License. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
7 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
8 * This program is distributed in the hope that it will be useful, |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
11 * GNU General Public License for more details. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
12 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
13 * For information on how to redistribute this software under |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
14 * the terms of a license other than GNU General Public License |
102
a3a2e5deb320
Updated contact address to support@hg4j.com
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
91
diff
changeset
|
15 * contact TMate Software at support@hg4j.com |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 */ |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
17 package org.tmatesoft.hg.repo; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
18 |
610
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
19 import static org.tmatesoft.hg.repo.HgRepositoryFiles.HgIgnore; |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
20 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
21 |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
22 import java.io.BufferedReader; |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
23 import java.io.File; |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
24 import java.io.FileReader; |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
25 import java.io.IOException; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
26 import java.util.ArrayList; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
27 import java.util.Collections; |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
28 import java.util.HashSet; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
29 import java.util.List; |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
30 import java.util.Set; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
31 import java.util.regex.Pattern; |
335
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
32 import java.util.regex.PatternSyntaxException; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
33 |
610
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
34 import org.tmatesoft.hg.internal.FileChangeMonitor; |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
35 import org.tmatesoft.hg.internal.Internals; |
141
8248aae33f7d
Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
114
diff
changeset
|
36 import org.tmatesoft.hg.util.Path; |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
37 import org.tmatesoft.hg.util.PathRewrite; |
141
8248aae33f7d
Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
114
diff
changeset
|
38 |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
39 /** |
141
8248aae33f7d
Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
114
diff
changeset
|
40 * Handling of ignored paths according to .hgignore configuration |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
41 * |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
42 * @author Artem Tikhomirov |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
15
diff
changeset
|
43 * @author TMate Software Ltd. |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
44 */ |
289
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
45 public class HgIgnore implements Path.Matcher { |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
46 |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
47 private List<Pattern> entries; |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
48 private final PathRewrite globPathHelper; |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
49 private FileChangeMonitor ignoreFileTracker; |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
50 // if pattern matches first fragment of a path, it will |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
51 // match any other path with this fragment, so we can avoid pattern matching |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
52 // if path starts with one of such fragments (often for e.g. ignored 'bin/' folders) |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
53 private final Set<String> ignoredFirstFragments; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
54 |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
55 HgIgnore(PathRewrite globPathRewrite) { |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
56 entries = Collections.emptyList(); |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
57 globPathHelper = globPathRewrite; |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
58 ignoredFirstFragments = new HashSet<String>(); |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
59 } |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
60 |
610
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
61 /* package-local */ void read(Internals repo) throws HgInvalidControlFileException { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
62 File ignoreFile = repo.getRepositoryFile(HgIgnore); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
63 BufferedReader fr = null; |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
64 try { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
65 if (ignoreFile.canRead() && ignoreFile.isFile()) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
66 fr = new BufferedReader(new FileReader(ignoreFile)); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
67 final List<String> errors = read(fr); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
68 if (errors != null) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
69 repo.getLog().dump(getClass(), Warn, "Syntax errors parsing %s:\n%s", ignoreFile.getName(), Internals.join(errors, ",\n")); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
70 } |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
71 } |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
72 if (ignoreFileTracker == null) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
73 ignoreFileTracker = new FileChangeMonitor(ignoreFile); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
74 } |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
75 ignoreFileTracker.touch(this); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
76 } catch (IOException ex) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
77 final String m = String.format("Error reading %s file", ignoreFile); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
78 throw new HgInvalidControlFileException(m, ex, ignoreFile); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
79 } finally { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
80 try { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
81 if (fr != null) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
82 fr.close(); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
83 } |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
84 } catch (IOException ex) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
85 repo.getLog().dump(getClass(), Warn, ex, null); // it's read, don't treat as error |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
86 } |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
87 } |
610
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
88 } |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
89 |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
90 /*package-local*/ void reloadIfChanged(Internals repo) throws HgInvalidControlFileException { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
91 assert ignoreFileTracker != null; |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
92 if (ignoreFileTracker.changed(this)) { |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
93 entries = Collections.emptyList(); |
5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
564
diff
changeset
|
94 read(repo); |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
95 } |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
96 } |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
97 |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
98 /* package-local */ List<String> read(BufferedReader content) throws IOException { |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
99 final String REGEXP = "regexp", GLOB = "glob"; |
564
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
100 final String REGEXP_PREFIX1 = REGEXP + ":", REGEXP_PREFIX2 = "re:", GLOB_PREFIX = GLOB + ":"; |
335
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
101 ArrayList<String> errors = new ArrayList<String>(); |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
102 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
103 String syntax = REGEXP; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
104 String line; |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
105 while ((line = content.readLine()) != null) { |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
106 line = line.trim(); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
107 if (line.startsWith("syntax:")) { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
108 syntax = line.substring("syntax:".length()).trim(); |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
109 if (!REGEXP.equals(syntax) && !GLOB.equals(syntax)) { |
335
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
110 errors.add(line); |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
111 continue; |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
112 //throw new IllegalStateException(line); |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
113 } |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
114 } else if (line.length() > 0) { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
115 // shall I account for local paths in the file (i.e. |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
116 // back-slashed on windows)? |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
117 int x, s = 0; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
118 while ((x = line.indexOf('#', s)) >= 0) { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
119 if (x > 0 && line.charAt(x-1) == '\\') { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
120 // remove escape char |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
121 line = line.substring(0, x-1).concat(line.substring(x)); |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
122 s = x; // with exclusion of char at [x], s now points to what used to be at [x+1] |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
123 } else { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
124 line = line.substring(0, x).trim(); |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
125 } |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
126 } |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
127 // due to the nature of Mercurial implementation, lines prefixed with syntax kind |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
128 // are processed correctly (despite the fact hgignore(5) suggest "syntax:<kind>" as the |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
129 // only way to specify it). lineSyntax below leaves a chance for the line to switch |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
130 // syntax in use without affecting default kind. |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
131 String lineSyntax; |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
132 if (line.startsWith(GLOB_PREFIX)) { |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
133 line = line.substring(GLOB_PREFIX.length()).trim(); |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
134 lineSyntax = GLOB; |
564
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
135 } else if (line.startsWith(REGEXP_PREFIX1)) { |
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
136 line = line.substring(REGEXP_PREFIX1.length()).trim(); |
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
137 lineSyntax = REGEXP; |
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
138 } else if (line.startsWith(REGEXP_PREFIX2)) { |
e6407313bab7
Recognize re: in-line prefix for regular expressions as native client does, despite silence in hgingore.5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
419
diff
changeset
|
139 line = line.substring(REGEXP_PREFIX2.length()).trim(); |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
140 lineSyntax = REGEXP; |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
141 } else { |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
142 lineSyntax = syntax; |
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
143 } |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
144 if (line.length() == 0) { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
145 continue; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
146 } |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
147 if (GLOB.equals(lineSyntax)) { |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
148 // hgignore(5) says slashes '\' are escape characters, |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
149 // however, for glob patterns on Windows first get backslashes converted to slashes |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
150 if (globPathHelper != null) { |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
151 line = globPathHelper.rewrite(line).toString(); |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
152 } |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
153 line = glob2regex(line); |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
154 } else { |
408
e732521a9eb4
Issue 28: support hgignore entries with syntax prefix
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
343
diff
changeset
|
155 assert REGEXP.equals(lineSyntax); |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
156 // regular expression patterns need not match start of the line unless demanded explicitly |
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
157 line = line.charAt(0) == '^' ? line : ".*" + line; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
158 } |
335
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
159 try { |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
160 result.add(Pattern.compile(line)); // case-sensitive |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
161 } catch (PatternSyntaxException ex) { |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
162 errors.add(line + "@" + ex.getMessage()); |
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
163 } |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
164 } |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
165 } |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
166 result.trimToSize(); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
167 entries = result; |
335
3d41dc148d14
Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
289
diff
changeset
|
168 return errors.isEmpty() ? null : errors; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
169 } |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
170 |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
171 // note, #isIgnored(), even if queried for directories and returned positive reply, may still get |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
172 // a file from that ignored folder to get examined. Thus, patterns like "bin" shall match not only a folder, |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
173 // but any file under that folder as well |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
174 // Alternatively, file walker may memorize folder is ignored and uses this information for all nested files. However, |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
175 // this approach would require walker (a) return directories (b) provide nesting information. This may become |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
176 // troublesome when one walks not over io.File, but Eclipse's IResource or any other custom VFS. |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
177 // |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
178 // |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
179 // might be interesting, although looks like of no direct use in my case |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
180 // @see http://stackoverflow.com/questions/1247772/is-there-an-equivalent-of-java-util-regex-for-glob-type-patterns |
289
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
181 // |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
182 // TODO consider refactoring to reuse in PathGlobMatcher#glob2regexp |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
183 private static String glob2regex(String line) { |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
184 assert line.length() > 0; |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
185 StringBuilder sb = new StringBuilder(line.length() + 10); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
186 int start = 0, end = line.length() - 1; |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
187 sb.append("(?:|.*/)"); // glob patterns shall match file in any directory |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
188 |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
189 int inCurly = 0; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
190 for (int i = start; i <= end; i++) { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
191 char ch = line.charAt(i); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
192 if (ch == '.' || ch == '\\') { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
193 sb.append('\\'); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
194 } else if (ch == '?') { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
195 // simple '.' substitution might work out, however, more formally |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
196 // a char class seems more appropriate to avoid accidentally |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
197 // matching a subdirectory with ? char (i.e. /a/b?d against /a/bad, /a/bed and /a/b/d) |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
198 // @see http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_03 |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
199 // quote: "The slash character in a pathname shall be explicitly matched by using one or more slashes in the pattern; |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
200 // it shall neither be matched by the asterisk or question-mark special characters nor by a bracket expression" |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
201 sb.append("[^/]"); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
202 continue; |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
203 } else if (ch == '*') { |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
204 sb.append("[^/]*?"); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
205 continue; |
269
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
206 } else if (ch == '{') { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
207 // XXX in fact, need to respect if last char was escaping ('\\'), then don't need to treat this as special |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
208 // see link at javadoc above for reasonable example |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
209 inCurly++; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
210 sb.append('('); |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
211 continue; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
212 } else if (ch == '}') { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
213 if (inCurly > 0) { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
214 inCurly--; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
215 sb.append(')'); |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
216 continue; |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
217 } |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
218 } else if (ch == ',' && inCurly > 0) { |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
219 sb.append('|'); |
7af843ecc378
Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
225
diff
changeset
|
220 continue; |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
221 } |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
222 sb.append(ch); |
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
223 } |
409
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
224 // Python impl doesn't keep empty segments in directory names (ntpath.normpath and posixpath.normpath), |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
225 // effectively removing trailing separators, thus patterns like "bin/" get translated into "bin$" |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
226 // Our glob rewriter doesn't strip last empty segment, and "bin/$" would be incorrect pattern, |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
227 // (e.g. isIgnored("bin/file") performs two matches, against "bin/file" and "bin") hence the check. |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
228 if (sb.charAt(sb.length() - 1) != '/') { |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
229 sb.append('$'); |
0f5696623512
Support glob path pattern rewrite to facilitate use of globs with Windows path separator
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
408
diff
changeset
|
230 } |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
231 return sb.toString(); |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
232 } |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
233 |
289
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
234 /** |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
235 * @param path file or directory name in question |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
236 * @return <code>true</code> if matches repository configuration of ignored files. |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
237 */ |
141
8248aae33f7d
Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
114
diff
changeset
|
238 public boolean isIgnored(Path path) { |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
239 String ps = path.toString(); |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
240 int x = ps.indexOf('/'); |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
241 if (x != -1 && ignoredFirstFragments.contains(ps.substring(0, x))) { |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
242 return true; |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
243 } |
91
c2ce1cfaeb9e
ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
244 for (Pattern p : entries) { |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
245 if (p.matcher(ps).find()) { |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
246 return true; |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
247 } |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
248 } |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
249 boolean firstFragment = true; |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
250 while (x != -1 && x+1 != ps.length() /*skip very last segment not to check complete string twice*/) { |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
251 String fragment = ps.substring(0, x); |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
252 for (Pattern p : entries) { |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
253 if (p.matcher(fragment).matches()) { |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
254 if (firstFragment) { |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
255 ignoredFirstFragments.add(new String(fragment)); |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
256 } |
342
516b817415ba
HgIgnore: regex patterns to match part of the filename do not work
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
339
diff
changeset
|
257 return true; |
339
863356c2847e
Issue 16: respect glob patterns in HgIgnore for sub-directories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
335
diff
changeset
|
258 } |
863356c2847e
Issue 16: respect glob patterns in HgIgnore for sub-directories
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
335
diff
changeset
|
259 } |
694
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
260 x = ps.indexOf('/', x+1); |
7efabe0cddcf
Speed up (a) file rename history to minimize file reads; (b) file.isCopy(int) to read metadata for few revisions at once (use pattern assumes earlier revisions are likely to be queried, too); (c) HgIgnore.isIgnored by caching matched initial fragments (to substitute more expensive Matcher.matches with cheaper HashMap.contains)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
610
diff
changeset
|
261 firstFragment = false; |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
262 } |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
263 return false; |
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
264 } |
289
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
265 |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
266 /** |
419
7f136a3fa671
Clean javadoc to fix obvious warnings
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
409
diff
changeset
|
267 * A handy wrap of {@link #isIgnored(Path)} into {@link org.tmatesoft.hg.util.Path.Matcher}. Yields same result as {@link #isIgnored(Path)}. |
289
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
268 * @return <code>true</code> if file is deemed ignored. |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
269 */ |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
270 public boolean accept(Path path) { |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
271 return isIgnored(path); |
086a326f181f
Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
271
diff
changeset
|
272 } |
15
865bf07f381f
Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
273 } |