-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ignore] Add extensive test for gitignore matching #551
Changes from 4 commits
4e19863
758addd
cf306fa
b109f1e
2b95766
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,8 +169,8 @@ impl Gitignore { | |
self.num_whitelists | ||
} | ||
|
||
/// Returns whether the given file path matched a pattern in this gitignore | ||
/// matcher. | ||
/// Returns whether the given path (file or directory) matched a pattern in | ||
/// this gitignore matcher. | ||
/// | ||
/// `is_dir` should be true if the path refers to a directory and false | ||
/// otherwise. | ||
|
@@ -191,6 +191,40 @@ impl Gitignore { | |
self.matched_stripped(self.strip(path.as_ref()), is_dir) | ||
} | ||
|
||
/// Returns whether the given path (file or directory) or any of its parent | ||
/// directories matched a pattern in this gitignore matcher. | ||
/// | ||
/// NOTE: This method is more expensive than walking the directory hierarchy | ||
/// top-to-bottom and matching the entries. But, it is useful in cases when | ||
/// a list of paths are available without a hierarchy. | ||
/// | ||
/// `is_dir` should be true if the path refers to a directory and false | ||
/// otherwise. | ||
/// | ||
/// The given path is matched relative to the path given when building | ||
/// the matcher. Specifically, before matching `path`, its prefix (as | ||
/// determined by a common suffix of the directory containing this | ||
/// gitignore) is stripped. If there is no common suffix/prefix overlap, | ||
/// then `path` is assumed to be relative to this matcher. | ||
pub fn matched_recursive<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match<&Glob> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we think of another name? I feel like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. Renamed to |
||
if self.is_empty() { | ||
return Match::None; | ||
} | ||
let mut current_path = self.strip(path.as_ref()); | ||
match self.matched_stripped(current_path, is_dir) { | ||
Match::None => { | ||
while let Some(parent) = current_path.parent() { | ||
match self.matched_stripped(parent, is_dir) { | ||
Match::None => current_path = parent, | ||
a_match => return a_match, | ||
} | ||
} | ||
} | ||
a_match => return a_match, | ||
} | ||
Match::None | ||
} | ||
|
||
/// Like matched, but takes a path that has already been stripped. | ||
fn matched_stripped<P: AsRef<Path>>( | ||
&self, | ||
|
@@ -440,7 +474,7 @@ impl GitignoreBuilder { | |
} | ||
|
||
/// Toggle whether the globs should be matched case insensitively or not. | ||
/// | ||
/// | ||
/// This is disabled by default. | ||
pub fn case_insensitive( | ||
&mut self, yes: bool | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
# Based on https://github.com/behnam/gitignore-test/blob/master/.gitignore | ||
|
||
### file in root | ||
|
||
# MATCH /file_root_1 | ||
file_root_00 | ||
|
||
# NO_MATCH | ||
file_root_01/ | ||
|
||
# NO_MATCH | ||
file_root_02/* | ||
|
||
# NO_MATCH | ||
file_root_03/** | ||
|
||
|
||
# MATCH /file_root_10 | ||
/file_root_10 | ||
|
||
# NO_MATCH | ||
/file_root_11/ | ||
|
||
# NO_MATCH | ||
/file_root_12/* | ||
|
||
# NO_MATCH | ||
/file_root_13/** | ||
|
||
|
||
# NO_MATCH | ||
*/file_root_20 | ||
|
||
# NO_MATCH | ||
*/file_root_21/ | ||
|
||
# NO_MATCH | ||
*/file_root_22/* | ||
|
||
# NO_MATCH | ||
*/file_root_23/** | ||
|
||
|
||
# MATCH /file_root_30 | ||
**/file_root_30 | ||
|
||
# NO_MATCH | ||
**/file_root_31/ | ||
|
||
# NO_MATCH | ||
**/file_root_32/* | ||
|
||
# NO_MATCH | ||
**/file_root_33/** | ||
|
||
|
||
### file in sub-dir | ||
|
||
# MATCH /parent_dir/file_deep_1 | ||
file_deep_00 | ||
|
||
# NO_MATCH | ||
file_deep_01/ | ||
|
||
# NO_MATCH | ||
file_deep_02/* | ||
|
||
# NO_MATCH | ||
file_deep_03/** | ||
|
||
|
||
# NO_MATCH | ||
/file_deep_10 | ||
|
||
# NO_MATCH | ||
/file_deep_11/ | ||
|
||
# NO_MATCH | ||
/file_deep_12/* | ||
|
||
# NO_MATCH | ||
/file_deep_13/** | ||
|
||
|
||
# MATCH /parent_dir/file_deep_20 | ||
*/file_deep_20 | ||
|
||
# NO_MATCH | ||
*/file_deep_21/ | ||
|
||
# NO_MATCH | ||
*/file_deep_22/* | ||
|
||
# NO_MATCH | ||
*/file_deep_23/** | ||
|
||
|
||
# MATCH /parent_dir/file_deep_30 | ||
**/file_deep_30 | ||
|
||
# NO_MATCH | ||
**/file_deep_31/ | ||
|
||
# NO_MATCH | ||
**/file_deep_32/* | ||
|
||
# NO_MATCH | ||
**/file_deep_33/** | ||
|
||
|
||
### dir in root | ||
|
||
# MATCH /dir_root_00 | ||
dir_root_00 | ||
|
||
# MATCH /dir_root_01 | ||
dir_root_01/ | ||
|
||
# MATCH /dir_root_02 | ||
dir_root_02/* | ||
|
||
# MATCH /dir_root_03 | ||
dir_root_03/** | ||
|
||
|
||
# MATCH /dir_root_10 | ||
/dir_root_10 | ||
|
||
# MATCH /dir_root_11 | ||
/dir_root_11/ | ||
|
||
# MATCH /dir_root_12 | ||
/dir_root_12/* | ||
|
||
# MATCH /dir_root_13 | ||
/dir_root_13/** | ||
|
||
|
||
# NO_MATCH | ||
*/dir_root_20 | ||
|
||
# NO_MATCH | ||
*/dir_root_21/ | ||
|
||
# NO_MATCH | ||
*/dir_root_22/* | ||
|
||
# NO_MATCH | ||
*/dir_root_23/** | ||
|
||
|
||
# MATCH /dir_root_30 | ||
**/dir_root_30 | ||
|
||
# MATCH /dir_root_31 | ||
**/dir_root_31/ | ||
|
||
# MATCH /dir_root_32 | ||
**/dir_root_32/* | ||
|
||
# MATCH /dir_root_33 | ||
**/dir_root_33/** | ||
|
||
|
||
### dir in sub-dir | ||
|
||
# MATCH /parent_dir/dir_deep_00 | ||
dir_deep_00 | ||
|
||
# MATCH /parent_dir/dir_deep_01 | ||
dir_deep_01/ | ||
|
||
# NO_MATCH | ||
dir_deep_02/* | ||
|
||
# NO_MATCH | ||
dir_deep_03/** | ||
|
||
|
||
# NO_MATCH | ||
/dir_deep_10 | ||
|
||
# NO_MATCH | ||
/dir_deep_11/ | ||
|
||
# NO_MATCH | ||
/dir_deep_12/* | ||
|
||
# NO_MATCH | ||
/dir_deep_13/** | ||
|
||
|
||
# MATCH /parent_dir/dir_deep_20 | ||
*/dir_deep_20 | ||
|
||
# MATCH /parent_dir/dir_deep_21 | ||
*/dir_deep_21/ | ||
|
||
# MATCH /parent_dir/dir_deep_22 | ||
*/dir_deep_22/* | ||
|
||
# MATCH /parent_dir/dir_deep_23 | ||
*/dir_deep_23/** | ||
|
||
|
||
# MATCH /parent_dir/dir_deep_30 | ||
**/dir_deep_30 | ||
|
||
# MATCH /parent_dir/dir_deep_31 | ||
**/dir_deep_31/ | ||
|
||
# MATCH /parent_dir/dir_deep_32 | ||
**/dir_deep_32/* | ||
|
||
# MATCH /parent_dir/dir_deep_33 | ||
**/dir_deep_33/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After the initial description, I think we should briefly explain what we mean by
parent
. That is, it is a transformation on the path itself and doesn't try to walk up the file system. I'm not sure how to say that succinctly and clearly though.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know what you mean. Added some more text here. Please see how that look?