summaryrefslogtreecommitdiff
path: root/src/ignore.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2018-02-01 10:36:33 +0000
committerPatrick Steinhardt <ps@pks.im>2018-02-01 10:46:20 +0000
commite28e17e60e7a73640a493918d610b9fe56e7f727 (patch)
treefa5712d320c999fe845bd624ca4151eebf6419fd /src/ignore.c
parent71c43065379ecdc523aa0d0c762fd9083fa0f8d9 (diff)
downloadlibgit2-e28e17e60e7a73640a493918d610b9fe56e7f727.tar.gz
attr: avoid stat'ting files for bare repositories
Depending on whether the path we want to look up an attribute for is a file or a directory, the fnmatch function will be called with different flags. Because of this, we have to first stat(3) the path to determine whether it is a file or directory in `git_attr_path__init`. This is wasteful though in bare repositories, where we can already be assured that the path will never exist at all due to there being no worktree. In this case, we will execute an unnecessary syscall, which might be noticeable on networked file systems. What happens right now is that we always pass the `GIT_DIR_FLAG_UNKOWN` flag to `git_attr_path__init`, which causes it to `stat` the file itself to determine its type. As it is calling `git_path_isdir` on the path, which will always return `false` in case the path does not exist, we end up with the path always being treated as a file in case of a bare repository. As such, we can just check the bare-repository case in all callers and then pass in `GIT_DIR_FLAG_FALSE` ourselves, avoiding the need to `stat`. While this may not always be correct, it at least is no different from our current behavior.
Diffstat (limited to 'src/ignore.c')
-rw-r--r--src/ignore.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/ignore.c b/src/ignore.c
index 615cd94bf..ddbcaf3bf 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -540,6 +540,7 @@ int git_ignore_path_is_ignored(
git_ignores ignores;
unsigned int i;
git_attr_file *file;
+ git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN;
assert(repo && ignored && pathname);
@@ -548,7 +549,10 @@ int git_ignore_path_is_ignored(
memset(&path, 0, sizeof(path));
memset(&ignores, 0, sizeof(ignores));
- if ((error = git_attr_path__init(&path, pathname, workdir, GIT_DIR_FLAG_UNKNOWN)) < 0 ||
+ if (git_repository_is_bare(repo))
+ dir_flag = GIT_DIR_FLAG_FALSE;
+
+ if ((error = git_attr_path__init(&path, pathname, workdir, dir_flag)) < 0 ||
(error = git_ignore__for_path(repo, path.path, &ignores)) < 0)
goto cleanup;