dir: synchronize treat_leading_path() and read_directory_recursive()
authorElijah Newren <newren@gmail.com>
Thu, 19 Dec 2019 21:28:25 +0000 (21:28 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 19 Dec 2019 21:45:47 +0000 (13:45 -0800)
commit777b420347649f26022bb1a4bf7afe7c4fe0b090
treecc2d74829130d0b9b483b6191fcb917bd1cf9a9d
parentb9670c1f5e6b98837c489a03ac0d343d30e08505
dir: synchronize treat_leading_path() and read_directory_recursive()

Our optimization to avoid calling into read_directory_recursive() when
all pathspecs have a common leading directory mean that we need to match
the logic that read_directory_recursive() would use if we had just
called it from the root.  Since it does more than call treat_path() we
need to copy that same logic.

Alternatively, we could try to change treat_path to return path_recurse
for an untracked directory under the given special circumstances that
this logic checks for, but a simple switch results in many test failures
such as 'git clean -d' not wiping out untracked but empty directories.
To work around that, we'd need the caller of treat_path to check for
path_recurse and sometimes special case it into path_untracked.  In
other words, we'd still have extra logic in both places.

Needing to duplicate logic like this means it is guaranteed someone will
eventually need to make further changes and forget to update both
locations.  It is tempting to just nuke the leading_directory special
casing to avoid such bugs and simplify the code, but unpack_trees'
verify_clean_subdirectory() also calls read_directory() and does so with
a non-empty leading path, so I'm hesitant to try to restructure further.
Add obnoxious warnings to treat_leading_path() and
read_directory_recursive() to try to warn people of such problems.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
dir.c
t/t3011-common-prefixes-and-directory-traversal.sh
t/t7061-wtstatus-ignore.sh