Hi Elijah, I have not had time to dive deeply into this, but I know that it _does_ cause a ton of segmentation faults in the `shears/pu` branch (where all of Git for Windows' patches are rebased on top of `pu`): On Tue, 10 Dec 2019, Elijah Newren via GitGitGadget wrote: > diff --git a/dir.c b/dir.c > index 645b44ea64..9c71a9ac21 100644 > --- a/dir.c > +++ b/dir.c > @@ -2102,37 +2102,69 @@ static int treat_leading_path(struct dir_struct *dir, > const struct pathspec *pathspec) > { > struct strbuf sb = STRBUF_INIT; > - int baselen, rc = 0; > + int prevlen, baselen; > const char *cp; > + struct cached_dir cdir; > + struct dirent de; > + enum path_treatment state = path_none; > + > + /* > + * For each directory component of path, we are going to check whether > + * that path is relevant given the pathspec. For example, if path is > + * foo/bar/baz/ > + * then we will ask treat_path() whether we should go into foo, then > + * whether we should go into bar, then whether baz is relevant. > + * Checking each is important because e.g. if path is > + * .git/info/ > + * then we need to check .git to know we shouldn't traverse it. > + * If the return from treat_path() is: > + * * path_none, for any path, we return false. > + * * path_recurse, for all path components, we return true > + * * <anything else> for some intermediate component, we make sure > + * to add that path to the relevant list but return false > + * signifying that we shouldn't recurse into it. > + */ > > while (len && path[len - 1] == '/') > len--; > if (!len) > return 1; > + > + memset(&cdir, 0, sizeof(cdir)); > + memset(&de, 0, sizeof(de)); > + cdir.de = &de; > + de.d_type = DT_DIR; So here, `de` is zeroed out, and therefore `de.d_name` is `NULL`. > baselen = 0; > + prevlen = 0; > while (1) { > - cp = path + baselen + !!baselen; > + prevlen = baselen + !!baselen; > + cp = path + prevlen; > cp = memchr(cp, '/', path + len - cp); > if (!cp) > baselen = len; > else > baselen = cp - path; > - strbuf_setlen(&sb, 0); > + strbuf_reset(&sb); > strbuf_add(&sb, path, baselen); > if (!is_directory(sb.buf)) > break; > - if (simplify_away(sb.buf, sb.len, pathspec)) > - break; > - if (treat_one_path(dir, NULL, istate, &sb, baselen, pathspec, > - DT_DIR, NULL) == path_none) > + strbuf_reset(&sb); > + strbuf_add(&sb, path, prevlen); > + memcpy(de.d_name, path+prevlen, baselen-prevlen); But here we try to copy a path into that `de.d_name`, which is still `NULL`? That can't be right, can it? Thanks for your help, Dscho > + de.d_name[baselen-prevlen] = '\0'; > + state = treat_path(dir, NULL, &cdir, istate, &sb, prevlen, > + pathspec); > + if (state != path_recurse) > break; /* do not recurse into it */ > - if (len <= baselen) { > - rc = 1; > + if (len <= baselen) > break; /* finished checking */ > - } > } > + add_path_to_appropriate_result_list(dir, NULL, &cdir, istate, > + &sb, baselen, pathspec, > + state); > + > strbuf_release(&sb); > - return rc; > + return state == path_recurse; > } > > static const char *get_ident_string(void) > diff --git a/t/t3011-common-prefixes-and-directory-traversal.sh b/t/t3011-common-prefixes-and-directory-traversal.sh > index d6e161ddd8..098fddc75b 100755 > --- a/t/t3011-common-prefixes-and-directory-traversal.sh > +++ b/t/t3011-common-prefixes-and-directory-traversal.sh > @@ -74,7 +74,7 @@ test_expect_success 'git ls-files -o --directory untracked_dir does not recurse' > test_cmp expect actual > ' > > -test_expect_failure 'git ls-files -o --directory untracked_dir/ does not recurse' ' > +test_expect_success 'git ls-files -o --directory untracked_dir/ does not recurse' ' > echo untracked_dir/ >expect && > git ls-files -o --directory untracked_dir/ >actual && > test_cmp expect actual > @@ -86,7 +86,7 @@ test_expect_success 'git ls-files -o untracked_repo does not recurse' ' > test_cmp expect actual > ' > > -test_expect_failure 'git ls-files -o untracked_repo/ does not recurse' ' > +test_expect_success 'git ls-files -o untracked_repo/ does not recurse' ' > echo untracked_repo/ >expect && > git ls-files -o untracked_repo/ >actual && > test_cmp expect actual > @@ -133,7 +133,7 @@ test_expect_success 'git ls-files -o .git shows nothing' ' > test_must_be_empty actual > ' > > -test_expect_failure 'git ls-files -o .git/ shows nothing' ' > +test_expect_success 'git ls-files -o .git/ shows nothing' ' > git ls-files -o .git/ >actual && > test_must_be_empty actual > ' > -- > gitgitgadget > > >