git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] read_directory: avoid invoking exclude machinery on tracked files

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 15, 2013, 14:17 UTC
Message-ID
<1360937848-4426-1-git-send-email-pclouds@gmail.com>

read_directory() (and its friendly wrapper fill_directory) collects untracked/ignored files by traversing through the whole worktree (*), feeding every entry to treat_one_path(), where each entry is checked against .gitignore patterns.

One may see that tracked files can't be excluded and we do not need to run them through exclude machinery. On repos where there are many .gitignore patterns and/or a lot of tracked files, this unnecessary processing can become expensive.

This patch avoids it mostly for normal cases. Directories are still processed as before. DIR_SHOW_IGNORED and DIR_COLLECT_IGNORED are not normally used unless some options are given (e.g. "checkout --overwrite-ignore", "add -f"...) so people still need to pay penalty in some cases, just not as often as before.

git status | webkit linux-2.6 libreoffice-core gentoo-x86 -------------+---------------------------------------------- before | 1.159s 0.226s 0.415s 0.597s after | 0.778s 0.176s 0.266s 0.556s nr. patterns | 89 376 19 0 nr. tracked | 182k 40k 63k 101k

(*) Not completely true. read_directory may skip recursing into a
    directory if it's entirely excluded and DIR_SHOW_OTHER_DIRECTORIES
    is not set.
Tracked-down-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 For reference:
 http://thread.gmane.org/gmane.comp.version-control.git/215820/focus=216195
 dir.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/dir.c b/dir.c
index 57394e4..bdff256 100644
--- a/dir.c
+++ b/dir.c
@@ -1244,7 +1244,19 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
 					  const struct path_simplify *simplify,
 					  int dtype, struct dirent *de)
 {
-	int exclude = is_excluded(dir, path->buf, &dtype);
+	int exclude;
+
+	if (dtype == DT_UNKNOWN)
+		dtype = get_dtype(de, path->buf, path->len);
+
+	if (!(dir->flags & DIR_SHOW_IGNORED) &&
+	    !(dir->flags & DIR_COLLECT_IGNORED) &&
+	    dtype != DT_DIR &&
+	    cache_name_exists(path->buf, path->len, ignore_case))
+		return path_ignored;
+
+	exclude = is_excluded(dir, path->buf, &dtype);
+
 	if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
 	    && exclude_matches_pathspec(path->buf, path->len, simplify))
 		dir_add_ignored(dir, path->buf, path->len);
@@ -1256,9 +1268,6 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
 	if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
 		return path_ignored;
 
-	if (dtype == DT_UNKNOWN)
-		dtype = get_dtype(de, path->buf, path->len);
-
 	switch (dtype) {
 	default:
 		return path_ignored;
-- 
1.8.1.2.536.gf441e6d
Next: Junio C Hamano
Message 1 of 12 in “read_directory: avoid invoking exclude machinery on tracked files”
  1. read_directory: avoid invoking exclude machinery on tracked filesNguyễn Thái Ngọc Duy, Feb 15, 2013
  2. Junio C HamanoFeb 15, 2013
  3. Duy NguyenFeb 15, 2013
  4. Junio C HamanoFeb 15, 2013
  5. Duy NguyenFeb 16, 2013
  6. Karsten BleesFeb 18, 2013
  7. read_directory: avoid invoking exclude machinery on tracked filesNguyễn Thái Ngọc Duy, Feb 16, 2013
  8. Pete WyckoffFeb 16, 2013
  9. Duy NguyenFeb 17, 2013
  10. Pete WyckoffFeb 17, 2013
  11. Junio C HamanoFeb 17, 2013
  12. dir.c: Make git-status --ignored even more consistentKarsten Blees, Feb 25, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.