Subject: Re: what should "git clean -n -f [-d] [-x] <pattern>" do?

From: Junio C Hamano <[email-masked]>
Date: Wed, 24 Jan 2024 09:21:32 -0800

Sergey Organov <[email-masked]> writes:

> Whereas obsoleting second -f in favor of new --nested-repo might be a
> good idea indeed, I believe it's still a mistake for "dry run" to
> somehow interfere with -f, sorry.

No need to be sorry ;-)

I actually think the true culprit of making this an odd-man-out is
that the use of "-f" in "git clean", especially with its use of the
configuration variable clean.requireForce that defaults to true, is
utterly non-standard.

The usual pattern of defining what "-f" does is that the "git foo"
command without any options does its common thing but refuses to
perform undesirable operations (e.g. "git add ."  adds everything
but refrains from adding ignored paths). And "git foo -f" is a way
to also perform what it commonly skips.

In contrast, with clean.requireForce that defaults to true, "git
clean" does not do anything useful by default.  Without such a
safety, "git clean" would be a way to clean expendable paths, and
"git clean -f" might be to also clean precious paths.  But it does
not work that way.  It always requires "-f" to do anything.  Worse
yet, it is not even "by default it acts as if -n is given and -f is
a way to countermand that implicit -n".  It is "you must give me
either -f (i.e. please do work) or -n (i.e. please show what you
would do) before I do anything".

  $ git clean
  fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean

Given that, it is hard to argue that it would be a natural end-user
expectation that the command does something useful (i.e. show what
would be done) when it is given "-f" and "-n" at the same time.
What makes this a rather nonsense UI is the fact that "-f" does not
work the way we would expect for this command.