If you're using git with zsh, you may have seen this:

% git show HEAD^1
zsh: no matches found: HEAD^1

…and wondered what in the name of all that is holy is going on.

The reason behind this is, that zsh signals an error if you provide it with a pattern, that doesn't match any files. This is the sane thing to do. Especially in interactive shells. If your shell behaves differently, I am sorry.

Your reaction might be “What pattern are you speaking of?” — since there is no asterisk, question mark or similar construct in there. That is true, but zsh has pretty powerful extended patterns, if enabled. They let you to pull off lots of things you might resort to regular expressions for, in certain situations. Characters like “#”, “~” and “^” become special characters and must be quoted if their special meaning is to be suppressed.

So that is what's going on. And sometimes git users get annoyed.

With git, though, you almost never want your shell to do any globbing anyway. Seriously. On the one hand, that is because git more often than not interacts with its database rather than with files, so files don't come into play to start with. And on the other hand, even when you pass stuff to git that looks like a file pattern, often you want git to expand the pattern itself. Like with “git grep”:

% git grep 'foo.*bar' -- '*.h'

This finds all lines that match the regular expression “foo.*bar” in all files that match the pattern “*.h”. No matter in which subdirectory the header file is hidden in.

Git is really one of the most eligible commands to have globbing (the expansion of patterns in file names) turned off for. And zsh let's you do that:

alias git='noglob git'

Now when you execute commands like these:

% git show HEAD^1
% git grep foo.*bar -- *.h

…zsh will not expand any patterns for list of files and instead hands all arguments over to git unchanged. Which is exactly what you want almost every time.

In the odd case, when you really do want the shell to do globbing, you can circumvent your shell from using the alias you just defined: In case you've got the EQUALS option set (which is the default) you can do:

% =git add *.txt

Try “echo =git” to see why that works.

If you don't use that particular option, you can always turn off alias expansion temporarily by prefixing the alias name with a backslash:

% \git add *.txt

And that's that.

Posted Mon 20 Jun 2016 21:55:38 CEST Tags: