threads / discuss / 57918

Error handling when giving empty command line arguments

Subject: Error handling when giving empty command line arguments

## tl;dr

6 messages between May 24, 2022 and May 25, 2022.

replies: 5people: 3as markdown or json

Olsson John· May 24, 2022, 13:25 UTC · lore
I have so far only seen this behavior with 'git fetch' command, but it might be more general depending on how command line parsing is implemented.
In a Bash script I had something similar to (but more complicated than what I show below)
  git fetch "${force}"
where $force is either an empty string or '--force'. Due to that you usually want to expand all variables within double quotes when writing Bash scripts I did not realize that I had made a mistake here. Instead I got this strange error message and spent a couple of hours chasing it
  fatal: no path specified; see 'git help pull' for valid url syntax
This problem eventually turned out to be of the trivial kind once I realized why I got it, and also very simple to reproduce. Just do
  $ git fetch ""
  fatal: no path specified; see 'git help pull' for valid url syntax
  $
That is, 'git fetch' does not check if the given string is an empty string before writing the error message. The empty string is completely unrelated to any path/URI and in this case it was not that helpful.
What do you say? Wouldn't it be better with a more specific error message when an option value/argument is an empty string? Or should perhaps empty strings be ignored by the git commands?
/John
Junio C Hamano· May 24, 2022, 22:51 UTC · re: Olsson John · lore

Re: Error handling when giving empty command line arguments

Olsson John <john.olsson@saabgroup.com> writes:
Show 10 quoted lines
>   git fetch "${force}"
> ...
>   $ git fetch ""
>   fatal: no path specified; see 'git help pull' for valid url syntax
>   $
> ...
> That is, 'git fetch' does not check if the given string is an
> empty string before writing the error message. The empty string is
> completely unrelated to any path/URI and in this case it was not
> that helpful.

The user is not giving enough information to Git to allow it to tell if "git fetch ''" it got came from any of these with unset variable:

	$ git fetch "$path"
	$ git fetch "$url"
	$ git fetch "$force"
because all Git sees is an empty string.

It is unfair to complain "is completely unrelated". The user didn't give enough information to even allow Git to tell if it is or is not related.

The message _is_ complaining about a malformed URL. You can fetch from a local repository by specifying the path to the directory, or you can fetch from a remote repository by specifying a URL. Since "" turns out to be neither a valid path or URL, the message hints that it didn't see any path or valid url on the command line. This is coming from connect.c::parse_connect_url() that does not know which end-user facing command ended up reaching there, so it is understandable that it picked a command that ought to be more familiar to users, i.e. "pull". FWIW,

	$ git ls-remote ""
would also give the same message that refers to "git help pull".

By the way, the "fatal" message talks about 'git help pull'; I wonder if it should say "git help fetch" instead, although they will refer to the same text included from Documentation/urls.txt.

Thanks.
Olsson John· May 25, 2022, 07:32 UTC · re: Junio C Hamano · lore

RE: [EXTERNAL] Re: Error handling when giving empty command line arguments

Show 9 quoted lines
> The user is not giving enough information to Git to allow it to tell if "git fetch ''" it got came from any of these with unset variable:
>
>	$ git fetch "$path"
>	$ git fetch "$url"
>	$ git fetch "$force"
>
> because all Git sees is an empty string.
>
> It is unfair to complain "is completely unrelated".  The user didn't give enough information to even allow Git to tell if it is or is not related.
That is exactly my point! I was thinking along the lines that perhaps the Git command(s) could complain about that it got an empty string as an argument since that is probably a mistake by the user due to that an empty string is neither a path, a URL/URI, or an option. It is thus an error case of its own.
The git checkout command actually complains about the case when you give it an empty string

$ git checkout "" feature/foobar fatal: empty string is not a valid pathspec. please use . instead if you want to match all paths

When it comes to git fetch it could assume that the given empty string is either a path or a URL/URI and write a similar error message. For instance

$ git fetch "" fatal: empty string is not a valid pathspec or URL; see 'git help fetch' for valid syntax

For me there is an important distinction between "no path specified" and "empty string". The former says that an argument is missing and the latter says that an argument is indeed given but it is an empty string.
Junio C Hamano· May 25, 2022, 15:46 UTC · re: Olsson John · lore

Re: [EXTERNAL] Re: Error handling when giving empty command line arguments

Olsson John <john.olsson@saabgroup.com> writes:
Show 5 quoted lines
> The git checkout command actually complains about the case when
> you give it an empty string
>
> $ git checkout "" feature/foobar
> fatal: empty string is not a valid pathspec. please use . instead if you want to match all paths

I actually knew that somebody new will bring up the message from "checkout", which special cases an empty parameter.

The reason why it gives an extra piece of guidance in this case is not because an empty string is something that can often come from a common mistake, like the "unset-variable-in-double-quotes" example that started this thread.

An empty string as a pathspec element used to mean "everything in the directory", but we deprecated that interpretation of an empty string, and then turned it into an error when somebody tried to use it. And that is why there is such a special case message. The purpose of it is primarily to help those who learned Git in older days and thought we still took "" as if it were ".".

So we do not give the same error message if you say
    $ git checkout "no-such-file" feature/foobar

when there is no "no-such-file". "" _is_ special in that case, and that is why we special case. For most other commands, it is not a good model to follow.

"git fetch", "git pull", "git ls-remote" never took an initial empty argument as something special that we later robbed its meaning and turned into an error.

Thanks.
Kevin Daudt· May 25, 2022, 04:41 UTC · re: Olsson John · lore

Re: Error handling when giving empty command line arguments

On Tue, May 24, 2022 at 01:25:43PM +0000, Olsson John wrote:
Show 22 quoted lines
> I have so far only seen this behavior with 'git fetch' command, but it might be more general depending on how command line parsing is implemented.
> 
> In a Bash script I had something similar to (but more complicated than what I show below)
> 
>   git fetch "${force}"
> 
> where $force is either an empty string or '--force'. Due to that you usually want to expand all variables within double quotes when writing Bash scripts I did not realize that I had made a mistake here. Instead I got this strange error message and spent a couple of hours chasing it
> 
>   fatal: no path specified; see 'git help pull' for valid url syntax
> 
> This problem eventually turned out to be of the trivial kind once I realized why I got it, and also very simple to reproduce. Just do
>   $ git fetch ""
>   fatal: no path specified; see 'git help pull' for valid url syntax
>   $
> 
> That is, 'git fetch' does not check if the given string is an empty string before writing the error message. The empty string is completely unrelated to any path/URI and in this case it was not that helpful.
> 
> What do you say? Wouldn't it be better with a more specific error message when an option value/argument is an empty string? Or should perhaps empty strings be ignored by the git commands?
> 
> 
> /John
> 
Hello John,

You are running into this issue because you use "$(force}" instead of ${force}. In the latter case, if $force is empty, the shell will not pass an empty string as an argument to git.

This does mean that it is subject to word splitting, but that can be an advantage as well if you decide you need more arguments than just '--force'. You should only use that in case you control what $force contains.

Hope this helps, Kevin

Olsson John· May 25, 2022, 07:03 UTC · re: Kevin Daudt · lore

RE: [EXTERNAL] Re: Error handling when giving empty command line arguments

> You are running into this issue because you use "$(force}" instead of ${force}. In the latter case, if $force is empty, the shell will not pass an empty string as an argument to git.
Yes, I know. I'm so used to always expanding variables within double quotes to avoid word splitting. And it doesn't help that I'm using shellcheck together with flycheck in Emacs so it constantly nags me about the danger of expanding variables without using double quotes. ;)
> This does mean that it is subject to word splitting, but that can be an advantage as well if you decide you need more arguments than just '--force'. You should only use that in case you control what $force contains.
Yes, I agree with you here.
-----Original Message-----
From: Kevin Daudt <me@ikke.info> 
Sent: den 25 maj 2022 06:42
To: Olsson John <john.olsson@saabgroup.com>
Cc: git@vger.kernel.org
Subject: [EXTERNAL] Re: Error handling when giving empty command line arguments
On Tue, May 24, 2022 at 01:25:43PM +0000, Olsson John wrote:
Show 27 quoted lines
> I have so far only seen this behavior with 'git fetch' command, but it might be more general depending on how command line parsing is implemented.
> 
> In a Bash script I had something similar to (but more complicated than 
> what I show below)
> 
>   git fetch "${force}"
> 
> where $force is either an empty string or '--force'. Due to that you 
> usually want to expand all variables within double quotes when writing 
> Bash scripts I did not realize that I had made a mistake here. Instead 
> I got this strange error message and spent a couple of hours chasing 
> it
> 
>   fatal: no path specified; see 'git help pull' for valid url syntax
> 
> This problem eventually turned out to be of the trivial kind once I realized why I got it, and also very simple to reproduce. Just do
>   $ git fetch ""
>   fatal: no path specified; see 'git help pull' for valid url syntax
>   $
> 
> That is, 'git fetch' does not check if the given string is an empty string before writing the error message. The empty string is completely unrelated to any path/URI and in this case it was not that helpful.
> 
> What do you say? Wouldn't it be better with a more specific error message when an option value/argument is an empty string? Or should perhaps empty strings be ignored by the git commands?
> 
> 
> /John
> 
Hello John,
You are running into this issue because you use "$(force}" instead of ${force}. In the latter case, if $force is empty, the shell will not pass an empty string as an argument to git.
This does mean that it is subject to word splitting, but that can be an advantage as well if you decide you need more arguments than just '--force'. You should only use that in case you control what $force contains.

Hope this helps, Kevin

← back to recent threads