]> git.ipfire.org Git - thirdparty/git.git/commitdiff
dir, clean: avoid disallowed behavior
authorElijah Newren <newren@gmail.com>
Thu, 11 Jun 2020 06:59:31 +0000 (06:59 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sat, 13 Jun 2020 00:27:16 +0000 (17:27 -0700)
dir.h documented quite clearly that DIR_SHOW_IGNORED and
DIR_SHOW_IGNORED_TOO are mutually exclusive, with a big comment to this
effect by the definition of both enum values.  However, a command like
   git clean -fx $DIR
would set both values for dir.flags.  I _think_ it happened to work
because:
  * As dir.h points out, DIR_KEEP_UNTRACKED_CONTENTS only takes effect
    if DIR_SHOW_IGNORED_TOO is set.
  * As coded, I believe DIR_SHOW_IGNORED would just happen to take
    precedence over DIR_SHOW_IGNORED_TOO in the code as currently
    constructed.
Which is a long way of saying "we just got lucky".

Fix clean.c to avoid setting these mutually exclusive values at the same
time, and add a check to dir.c that will throw a BUG() to prevent anyone
else from making this mistake.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/clean.c
dir.c

index 4ca12bc0c0ba2c3bc3084a320835cf83600173ce..3ca940f83a2f97e9e204be50eefe928190c392b9 100644 (file)
@@ -954,7 +954,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
                remove_directories = 1;
        }
 
-       if (remove_directories)
+       if (remove_directories && !ignored_only)
                dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;
 
        if (read_cache() < 0)
diff --git a/dir.c b/dir.c
index 6fb2f8ecdd71da881db7eea9f573a1893ca6ffdc..a3ad9702d646649477a37ce94a1f3b6c22e27f21 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -193,6 +193,10 @@ int fill_directory(struct dir_struct *dir,
        const char *prefix;
        size_t prefix_len;
 
+       unsigned exclusive_flags = DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO;
+       if ((dir->flags & exclusive_flags) == exclusive_flags)
+               BUG("DIR_SHOW_IGNORED and DIR_SHOW_IGNORED_TOO are exclusive");
+
        /*
         * Calculate common prefix for the pathspec, and
         * use that to optimize the directory walk