Junio C Hamano <gitster@xxxxxxxxx> writes: > Todd Rinaldo <toddr@xxxxxxxxxx> writes: > >> I think I have found a new bug in 1.7.5: > > My quick check indicates 1.7.3 behaves the same way, and 1.7.2.5 didn't > have --exclude option, so this does not seem to be anything particularly > new in the 1.7.5 release. > >> # The problem (Why is foo/ removed?) >> $>git clean -dXf --exclude=/foo >> Removing bar/ >> Removing foo/ > > Why is this command line giving -X that tells us not to use the ignore > rules, and --exclude option at the same time? The documentation and the implementation of "git clean" is quite confused. Here is what is said about "-e": -e <pattern>:: --exclude=<pattern>:: Specify special exceptions to not be cleaned. Each <pattern> is the same form as in $GIT_DIR/info/excludes and this option can be given multiple times. But in reality, it is not about "not be cleaned" at all. A better description to reflect what the implementation actually does is probably this: In addition to what are found in usual places like .gitignore (per directory) and $GIT_DIR/info/exclude, consider these patterns to be in the ignore rules. This mirrors what --exclude parameter to "ls-files" does [*1*]. I can however see a use case where the user wants to say something like this which is quite different: I know "git clean" (or "git clean -x" or "git clean -X") will try to remove paths A, B and C. I want it remove them except for this particular path C by adding --except=C option to the command line. And the current documentation does look like it is describing such an option. But that is not what --exclude option is about. One solution might be to say "I know the usual rules stored in .gitignore and the like tell us to that 'foo' is ignored (and to be cleaned), but for this invocation only, please treat 'foo' is _not_ ignored.", and there indeed is a way to do so: $ git clean -d -X -e \!foo (the backslash before '!' is to avoid history substitution in some shells). [Footnote] *1* This part in builtin/clean.c looks a bit distasteful: for (i = 0; i < exclude_list.nr; i++) add_exclude(exclude_list.items[i].string, "", 0, dir.exclude_list); The last parameter should be &dir.exclude_list[EXC_CMDL] because we are adding exclude patterns from the command line. It works by accident only because EXC_CMDL happens to be defined as 0. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html