@@ -2455,6 +2455,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
if (open_cached_dir(&cdir, dir, untracked, istate, &path, check_only))
goto out;
+ dir->visited_directories++;
if (untracked)
untracked->check_only = !!check_only;
@@ -2463,6 +2464,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
/* check how the file or directory should be treated */
state = treat_path(dir, untracked, &cdir, istate, &path,
baselen, pathspec);
+ dir->visited_paths++;
if (state > dir_state)
dir_state = state;
@@ -2778,6 +2780,10 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
static void trace2_read_directory_statistics(struct dir_struct *dir,
struct repository *repo)
{
+ trace2_data_intmax("read_directory", repo,
+ "directories-visited", dir->visited_directories);
+ trace2_data_intmax("read_directory", repo,
+ "paths-visited", dir->visited_paths);
if (!dir->untracked)
return;
trace2_data_intmax("read_directory", repo,
@@ -2798,6 +2804,8 @@ int read_directory(struct dir_struct *dir, struct index_state *istate,
struct untracked_cache_dir *untracked;
trace2_region_enter("dir", "read_directory", istate->repo);
+ dir->visited_paths = 0;
+ dir->visited_directories = 0;
if (has_symlink_leading_path(path, len)) {
trace_performance_leave("read directory %.*s", len, path);
@@ -336,6 +336,10 @@ struct dir_struct {
struct oid_stat ss_info_exclude;
struct oid_stat ss_excludes_file;
unsigned unmanaged_exclude_files;
+
+ /* Stats about the traversal */
+ unsigned visited_paths;
+ unsigned visited_directories;
};
/*Count the number of slashes for string s*/
@@ -65,6 +65,7 @@ get_relevant_traces() {
INPUT_FILE=$1
OUTPUT_FILE=$2
grep data.*read_directo $INPUT_FILE \
+ | grep -v visited \
| cut -d "|" -f 9 \
>$OUTPUT_FILE
}
@@ -747,42 +747,24 @@ test_expect_success 'clean untracked paths by pathspec' '
'
test_expect_success 'avoid traversing into ignored directories' '
- test_when_finished rm -f output error &&
+ test_when_finished rm -f output error trace.* &&
test_create_repo avoid-traversing-deep-hierarchy &&
(
cd avoid-traversing-deep-hierarchy &&
- >directory-random-file.txt &&
- # Put this file under directory400/directory399/.../directory1/
- depth=400 &&
- for x in $(test_seq 1 $depth); do
- mkdir "tmpdirectory$x" &&
- mv directory* "tmpdirectory$x" &&
- mv "tmpdirectory$x" "directory$x"
- done &&
-
- git clean -ffdxn -e directory$depth >../output 2>../error &&
-
- test_must_be_empty ../output &&
- # We especially do not want things like
- # "warning: could not open directory "
- # appearing in the error output. It is true that directories
- # that are too long cannot be opened, but we should not be
- # recursing into those directories anyway since the very first
- # level is ignored.
- test_must_be_empty ../error &&
-
- # alpine-linux-musl fails to "rm -rf" a directory with such
- # a deeply nested hierarchy. Help it out by deleting the
- # leading directories ourselves. Super slow, but, what else
- # can we do? Without this, we will hit a
- # error: Tests passed but test cleanup failed; aborting
- # so do this ugly manual cleanup...
- while test ! -f directory-random-file.txt; do
- name=$(ls -d directory*) &&
- mv $name/* . &&
- rmdir $name
- done
+ mkdir -p untracked/subdir/with/a &&
+ >untracked/subdir/with/a/random-file.txt &&
+
+ GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+ git clean -ffdxn -e untracked &&
+
+ grep data.*read_directo.*visited ../trace.output \
+ | cut -d "|" -f 9 >../trace.relevant &&
+ cat >../trace.expect <<-EOF &&
+ directories-visited:1
+ paths-visited:4
+ EOF
+ test_cmp ../trace.expect ../trace.relevant
)
'