Subject: [PATCH v4 00/12] Fix some git clean issues

From: Elijah Newren <[email-masked]>
Date: Tue, 17 Sep 2019 09:34:52 -0700

This patch series fixes a few issues with git-clean:
  * Failure to clean when multiple pathspecs are specified, reported both
    in April 2018[1] and again in May 2019[2].
  * Failure to preserve both tracked and untracked files within a nested
    Git repository reported a few weeks ago by SZEDER[3].
It builds on sg/clean-nested-repo-with-ignored.

[1] https://public-inbox.org/git/[email-masked]/
[2] https://public-inbox.org/git/[email-masked]/
[3] https://public-inbox.org/git/[email-masked]/

Changes since v3:
  * Clarified a couple commit messages highlighted by Junio.

Elijah Newren (12):
  t7300: add testcases showing failure to clean specified pathspecs
  dir: fix typo in comment
  dir: fix off-by-one error in match_pathspec_item
  dir: also check directories for matching pathspecs
  dir: make the DO_MATCH_SUBMODULE code reusable for a non-submodule
    case
  dir: if our pathspec might match files under a dir, recurse into it
  dir: add commentary explaining match_pathspec_item's return value
  git-clean.txt: do not claim we will delete files with -n/--dry-run
  clean: disambiguate the definition of -d
  clean: avoid removing untracked files in a nested git repository
  clean: rewrap overly long line
  clean: fix theoretical path corruption

 Documentation/git-clean.txt | 16 +++++-----
 builtin/clean.c             | 15 +++++++--
 dir.c                       | 63 +++++++++++++++++++++++++++----------
 dir.h                       |  8 +++--
 t/t7300-clean.sh            | 44 +++++++++++++++++++++++---
 5 files changed, 112 insertions(+), 34 deletions(-)

Range-diff:
 1:  fe35ab8cc3 !  1:  a48d4e7faf t7300: add testcases showing failure to clean specified pathspecs
    @@ -28,9 +28,15 @@
         showed that the same buggy behavior exists without using that flag, and
         has in fact existed since before cf424f5fd89b.
     
    -    Add testcases showing that multiple untracked files within entirely
    -    untracked directories cannot be cleaned when specifying these files to
    -    git clean via pathspecs.
    +    Although these problems at first are perceived to be different (e.g.
    +    never clearing out the requested files vs. taking multiple invocations
    +    to get everything cleared out), they are actually just different
    +    manifestations of the same problem.  The case with multiple directories
    +    that have no tracked files is the more general case; solving it will
    +    solve all the others.  So, I concentrate on it.  Add testcases showing
    +    that multiple untracked files within entirely untracked directories
    +    cannot be cleaned when specifying these files to git clean via
    +    pathspecs.
     
         Signed-off-by: Elijah Newren <[email-masked]>
     
 2:  707d287d79 =  2:  eb00b46822 dir: fix typo in comment
 3:  bb316e82b2 !  3:  c0e5b820a9 dir: fix off-by-one error in match_pathspec_item
    @@ -6,11 +6,22 @@
         namelen will be 4, and match[namelen] will be 'b'.  The correct location
         of the directory separator is namelen-1.
     
    -    The reason the code worked anyway was that the following code immediately
    -    checked whether the first matchlen characters matched (which they do) and
    -    then bailed and return MATCHED_RECURSIVELY anyway since wildmatch doesn't
    -    have the ability to check if "name" can be matched as a directory (or
    -    prefix) against the pathspec.
    +    However, other callers of match_pathspec_item() such as builtin/grep.c's
    +    submodule_path_match() will compare against a path named "foo" instead of
    +    "foo/".  It might be better to change all the callers to be consistent,
    +    as discussed at
    +       https://public-inbox.org/git/[email-masked]/
    +    and
    +       https://public-inbox.org/git/[email-masked]/
    +    but there are many cases to audit, so for now just make sure we handle
    +    both cases with and without a trailing slash.
    +
    +    The reason the code worked despite this sometimes-off-by-one error was
    +    that the subsequent code immediately checked whether the first matchlen
    +    characters matched (which they do) and then bailed and return
    +    MATCHED_RECURSIVELY anyway since wildmatch doesn't have the ability to
    +    check if "name" can be matched as a directory (or prefix) against the
    +    pathspec.
     
         Signed-off-by: Elijah Newren <[email-masked]>
     
 4:  56319f934a =  4:  397775ec35 dir: also check directories for matching pathspecs
 5:  81593a565c =  5:  b836de82c0 dir: make the DO_MATCH_SUBMODULE code reusable for a non-submodule case
 6:  9566823a0f =  6:  feb317d090 dir: if our pathspec might match files under a dir, recurse into it
 7:  7821898ba7 =  7:  0a574d6779 dir: add commentary explaining match_pathspec_item's return value
 8:  13def5df57 =  8:  0eaa08537c git-clean.txt: do not claim we will delete files with -n/--dry-run
 9:  e6b274abf7 =  9:  a1438301bb clean: disambiguate the definition of -d
10:  5f4ef14765 = 10:  8dc21923ee clean: avoid removing untracked files in a nested git repository
11:  4e30e62eb1 = 11:  707b6a5509 clean: rewrap overly long line
12:  de2444f7cb = 12:  84a90010ed clean: fix theoretical path corruption
-- 
2.22.1.17.g6e632477f7.dirty