From 755c6e5c06fc38903fa0d66be68a9c8ffa525c1b Mon Sep 17 00:00:00 2001
From: Evan Moses <evan@emoses.org>
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]