summaryrefslogtreecommitdiff
path: root/src/ignore.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-04-18 10:32:35 -0700
committerRussell Belfer <rb@github.com>2014-04-18 10:32:35 -0700
commit6a0956e504328f6584af971e840c202ecb21b5b6 (patch)
tree234b3fc25eecccc41a6cafe7c7322eb476b67569 /src/ignore.c
parent3c69bebc1c18444e9358c33f56c7cfefea4d1a8f (diff)
downloadlibgit2-6a0956e504328f6584af971e840c202ecb21b5b6.tar.gz
Pop ignore only if whole relative path matches
When traversing the directory structure, the iterator pushes and pops ignore files using a vector. Some directories don't have ignore files, so it uses a path comparison to decide when it is right to actually pop the last ignore file. This was only comparing directory suffixes, though, so a subdirectory with the same name as a parent could result in the parent's .gitignore being popped off the list ignores too early. This changes the logic to compare the entire relative path of the ignore file.
Diffstat (limited to 'src/ignore.c')
-rw-r--r--src/ignore.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/ignore.c b/src/ignore.c
index deae204f8..b08ff2200 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -123,7 +123,7 @@ int git_ignore__for_path(
int error = 0;
const char *workdir = git_repository_workdir(repo);
- assert(ignores);
+ assert(ignores && path);
memset(ignores, 0, sizeof(*ignores));
ignores->repo = repo;
@@ -140,10 +140,13 @@ int git_ignore__for_path(
if (workdir && git_path_root(path) < 0)
error = git_path_find_dir(&ignores->dir, path, workdir);
else
- error = git_buf_sets(&ignores->dir, path);
+ error = git_buf_joinpath(&ignores->dir, path, "");
if (error < 0)
goto cleanup;
+ if (workdir && !git__prefixcmp(ignores->dir.ptr, workdir))
+ ignores->dir_root = strlen(workdir);
+
/* set up internals */
if ((error = get_internal_ignores(&ignores->ign_internal, repo)) < 0)
goto cleanup;
@@ -204,10 +207,10 @@ int git_ignore__pop_dir(git_ignores *ign)
if ((end = strrchr(start, '/')) != NULL) {
size_t dirlen = (end - start) + 1;
+ const char *relpath = ign->dir.ptr + ign->dir_root;
+ size_t pathlen = ign->dir.size - ign->dir_root;
- if (ign->dir.size >= dirlen &&
- !memcmp(ign->dir.ptr + ign->dir.size - dirlen, start, dirlen))
- {
+ if (pathlen == dirlen && !memcmp(relpath, start, dirlen)) {
git_vector_pop(&ign->ign_path);
git_attr_file__free(file);
}