From 755c6e5c06fc38903fa0d66be68a9c8ffa525c1b Mon Sep 17 00:00:00 2001 From: Evan Moses Date: Thu, 9 Jan 2020 17:34:44 -0800 Subject: [PATCH] Fix ignore patterns in subdirectories with leading slashes Currenetly if you have an ignore file in a subdirectory "sub" with a pattern like /ignorethis The directory sub/ignorethis will be ignored if you run ag from within sub, but it won't be ignored if you run it from sub's parent. that is $ ag needle will search files in sub/ignorethis, but $ cd sub $ ag needle Will not. This is a bug --- src/ignore.c | 8 ++++++-- tests/ignore_slash_in_subdir.t | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/ignore_slash_in_subdir.t diff --git a/src/ignore.c b/src/ignore.c index fa4188919..1d1c07b13 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -206,6 +206,7 @@ static int ackmate_dir_match(const char *dir_name) { /* This is the hottest code in Ag. 10-15% of all execution time is spent here */ static int path_ignore_search(const ignores *ig, const char *path, const char *filename) { char *temp; + int temp_start_pos; size_t i; int match_pos; @@ -216,9 +217,12 @@ static int path_ignore_search(const ignores *ig, const char *path, const char *f } ag_asprintf(&temp, "%s/%s", path[0] == '.' ? path + 1 : path, filename); + //ig->abs_path has its leading slash stripped, so we have to strip the leading slash + //of temp as well + temp_start_pos = (temp[0] == '/') ? 1 : 0; - if (strncmp(temp, ig->abs_path, ig->abs_path_len) == 0) { - char *slash_filename = temp + ig->abs_path_len; + if (strncmp(temp+temp_start_pos, ig->abs_path, ig->abs_path_len) == 0) { + char *slash_filename = temp + temp_start_pos + ig->abs_path_len; if (slash_filename[0] == '/') { slash_filename++; } diff --git a/tests/ignore_slash_in_subdir.t b/tests/ignore_slash_in_subdir.t new file mode 100644 index 000000000..167d6ffb4 --- /dev/null +++ b/tests/ignore_slash_in_subdir.t @@ -0,0 +1,19 @@ +Setup: + + $ . $TESTDIR/setup.sh + $ mkdir -p subdir/ignoredir + $ mkdir ignoredir + $ printf 'match1\n' > subdir/ignoredir/file1.txt + $ printf 'match1\n' > ignoredir/file1.txt + $ printf '/ignoredir\n' > subdir/.ignore + +Ignore file in subdir/ignoredir, but not in ignoredir: + + $ ag match + ignoredir/file1.txt:1:match1 + +From subdir, ignore file in subdir/ignoredir: + + $ cd subdir + $ ag match + [1]